Warum funktioniert Decimal.Divide (int, int), aber nicht (int / int)?

105

Wie kommt es, dass das Teilen von zwei 32-Bit-Int-Zahlen als (int / int) zu mir zurückkehrt 0, aber wenn ich benutze, Decimal.Divide()erhalte ich die richtige Antwort? Ich bin auf keinen Fall ein Kerl.

Liam
quelle
1
Können Sie ein konkretes Beispiel nennen? Dezimal ist ein anderer Typ als Int32.
Groo
Übrigens habe ich Decimal gefunden. Divide verwendet nur Dezimalstellen als Eingabe.
Ravi
Decimal.Divide funktioniert auch für Ganzzahlen als Eingabe.
Thamarai T

Antworten:

214

intist ein ganzzahliger Typ; Das Teilen von zwei Ints führt eine Ganzzahldivision durch , dh der Bruchteil wird abgeschnitten, da er (auch int!) nicht im Ergebnistyp gespeichert werden kann . Decimalhat dagegen einen Bruchteil. Durch das Aufrufen Decimal.Dividewerden Ihre intArgumente implizit in Decimals konvertiert .

Sie können eine nicht ganzzahlige Unterteilung von intArgumenten erzwingen, indem Sie mindestens eines der Argumente explizit in einen Gleitkommatyp umwandeln, z.

int a = 42;
int b = 23;
double result = (double)a / b;
Konrad Rudolph
quelle
2
Gute Antwort. Ich habe auch Decimal.Divide (a, b) ausprobiert, was das gleiche Ergebnis ergab.
Baxter
6

Im ersten Fall führen Sie eine Ganzzahldivision durch, sodass das Ergebnis abgeschnitten wird (der Dezimalteil wird abgeschnitten) und eine Ganzzahl zurückgegeben wird.

Im zweiten Fall werden die Ints zuerst in Dezimalstellen umgewandelt, und das Ergebnis ist eine Dezimalzahl. Daher werden sie nicht abgeschnitten und Sie erhalten das richtige Ergebnis.

Andrew Rollings
quelle
4

Die folgende Zeile:

int a = 1, b = 2;
object result = a / b;

... wird mit ganzzahliger Arithmetik ausgeführt . Decimal.DivideAuf der anderen Seite werden zwei Parameter des Typs verwendet Decimal, sodass die Division eher nach Dezimalwerten als nach ganzzahligen Werten durchgeführt wird. Das entspricht:

int a = 1, b = 2;
object result = (Decimal)a / (Decimal)b;

Um dies zu untersuchen, können Sie nach jedem der obigen Beispiele die folgenden Codezeilen hinzufügen:

Console.WriteLine(result.ToString());
Console.WriteLine(result.GetType().ToString());

Die Ausgabe im ersten Fall wird sein

0
System.Int32

..und im zweiten Fall:

0,5
System.Decimal
Fredrik Mörk
quelle
2

Ich gehe davon aus, dass Decimal.Divide(decimal, decimal)die 2 int-Argumente implizit in Dezimalzahlen konvertiert werden, bevor ein Dezimalwert (präzise) zurückgegeben wird, wobei 4/5 als Ganzzahldivision behandelt wird und 0 zurückgibt

Gishu
quelle
1

Sie möchten die Zahlen umwandeln:

doppeltes c = (doppeltes) a / (doppeltes) b;

Hinweis: Wenn eines der Argumente in C # ein Double ist, wird eine doppelte Division verwendet, die zu einem Double führt. Folgendes würde also auch funktionieren:

doppeltes c = (doppeltes) a / b;

Hier ist ein kleines Programm:

static void Main(string[] args)
        {
            int a=0, b = 0, c = 0;
            int n = Convert.ToInt16(Console.ReadLine());
            string[] arr_temp = Console.ReadLine().Split(' ');
            int[] arr = Array.ConvertAll(arr_temp, Int32.Parse);
            foreach (int i in arr)
            {
                if (i > 0) a++;
                else if (i < 0) b++;
                else c++;
            }
            Console.WriteLine("{0}", (double)a / n);
            Console.WriteLine("{0}", (double)b / n);
            Console.WriteLine("{0}", (double)c / n);
            Console.ReadKey();
        }
Jaydeep Shil
quelle
0

Wenn Sie nach einer Antwort von 0 <a <1 suchen, reicht int / int nicht aus. int / int führt eine Ganzzahldivision durch. Versuchen Sie, einen der Ints innerhalb der Operation auf ein Double zu setzen.

Brian
quelle
1
Int32 ist eine vorzeichenbehaftete Ganzzahl. Meinten Sie 0 <Antwort <1?
Groo
0

In meinem Fall hat oben nichts funktioniert.

Ich möchte 278 durch 575 teilen und mit 100 multiplizieren, um den Prozentsatz zu ermitteln.

double p = (double)((PeopleCount * 1.0 / AllPeopleCount * 1.0) * 100.0);

%: 48,3478260869565 -> 278/575 ---> 0%: 51,6521739130435 -> 297/575 ---> 0

Wenn ich den PeopleCount mit 1,0 multipliziere, wird er dezimal und die Division wird 48,34 sein ... auch mit 100,0 multiplizieren, nicht mit 100.

Alp Altunel
quelle
-1

Die als solche gekennzeichnete Antwort ist fast da, aber ich denke, es lohnt sich hinzuzufügen, dass es einen Unterschied zwischen der Verwendung von double und decimal gibt.

Ich würde die Konzepte nicht besser erklären als Wikipedia, daher werde ich nur die Hinweise geben:

Gleitkomma-Arithmetik

Dezimaldatentyp

In Finanzsystemen ist es häufig erforderlich, dass wir eine bestimmte Anzahl von (Basis-10) Dezimalstellengenauigkeiten garantieren können. Dies ist im Allgemeinen nicht möglich, wenn sich die Eingabe- / Quelldaten in Basis 10 befinden, wir jedoch die Arithmetik in Basis 2 ausführen (da die Anzahl der Dezimalstellen, die für die Dezimalerweiterung einer Zahl erforderlich sind, von der Basis abhängt; ein Drittel benötigt unendlich viele Dezimalstellen Stellen, die in Basis-10 als 0,333333 ausgedrückt werden sollen ..., aber in Basis-3 wird nur eine Dezimalstelle benötigt: 0,1).

Gleitkommazahlen sind schneller zu verarbeiten (in Bezug auf die CPU-Zeit; programmtechnisch sind sie ebenso einfach) und werden immer dann bevorzugt, wenn Sie Rundungsfehler minimieren möchten (wie in wissenschaftlichen Anwendungen).

Dojo
quelle
1
Nichts in Ihrer Antwort dient dazu, die ursprüngliche Frage zu beantworten
LordWilmore