Antworten:
Die beiden Operanden (1 und 3) sind ganze Zahlen, daher wird eine ganzzahlige Arithmetik (Division hier) verwendet. Wenn Sie die Ergebnisvariable als double deklarieren, wird nach der Division nur eine implizite Konvertierung durchgeführt .
Eine ganzzahlige Division gibt natürlich das wahre Ergebnis einer gegen Null gerundeten Division zurück. Das Ergebnis von 0.333...
wird hier also auf 0 abgerundet. (Beachten Sie, dass der Prozessor eigentlich keine Rundung durchführt, aber Sie können sich das immer noch so vorstellen.)
Beachten Sie außerdem, dass beide Operanden (Zahlen) als Gleitkommazahlen angegeben werden. 3.0 und 1.0 oder auch nur die erste , dann wird Gleitkomma-Arithmetik verwendet 0.333...
.
DOWN
gegen Null. Die Rundung FLOOR
geht in Richtung negative Unendlichkeit.
1/3
verwendet die Ganzzahldivision, da beide Seiten Ganzzahlen sind.
Sie brauchen mindestens einen von ihnen zu sein float
oder double
.
Wenn Sie die Werte wie in Ihrer Frage in den Quellcode eingeben, können Sie dies tun 1.0/3
. Das 1.0
ist ein Doppel.
Wenn Sie die Werte von einer anderen Stelle erhalten, können Sie sie in eine (double)
verwandeln .int
double
int x = ...;
int y = ...;
double value = ((double) x) / y;
du solltest benutzen
double g=1.0/3;
oder
double g=1/3.0;
Die Ganzzahldivision gibt eine Ganzzahl zurück.
Weil Sie eine ganzzahlige Division durchführen.
Wie @Noldorin sagt, wird die Ganzzahldivision verwendet, wenn beide Operatoren Ganzzahlen sind.
Das Ergebnis 0.33333333 kann nicht als Ganzzahl dargestellt werden, daher wird dem Ergebnis nur der Ganzzahlteil (0) zugewiesen.
Wenn einer der Operatoren ein double
/ ist float
, findet eine Gleitkomma-Arithmetik statt. Aber Sie werden das gleiche Problem haben, wenn Sie das tun:
int n = 1.0 / 3.0;
Da 1 und 3 als Ganzzahlen behandelt werden, wird das Ergebnis auf 0 abgerundet, sodass es eine Ganzzahl ist.
Um das gewünschte Ergebnis zu erzielen, teilen Sie Java explizit mit, dass die Zahlen wie folgt doppelt sind:
double g = 1.0/3.0;
Die Konvertierung in JAVA ist recht einfach, erfordert jedoch etwas Verständnis. Wie im JLS für ganzzahlige Operationen erläutert :
Wenn ein anderer ganzzahliger Operator als ein Verschiebungsoperator mindestens einen Operanden vom Typ long hat, wird die Operation mit einer Genauigkeit von 64 Bit ausgeführt, und das Ergebnis des numerischen Operators ist vom Typ long. Wenn der andere Operand nicht lang ist, wird er zuerst erweitert (§5.1.5), um durch numerische Heraufstufung lang zu tippen (§5.6).
Und ein Beispiel ist immer der beste Weg, um das JLS zu übersetzen;)
int + long -> long
int(1) + long(2) + int(3) -> long(1+2) + long(3)
Andernfalls wird die Operation mit 32-Bit-Genauigkeit ausgeführt, und das Ergebnis des numerischen Operators ist vom Typ int. Wenn einer der Operanden kein int ist, wird er zunächst durch numerische Heraufstufung erweitert, um int einzugeben.
short + int -> int + int -> int
Ein kleines Beispiel mit Eclipse zeigt, dass selbst das Hinzufügen von zwei short
s nicht so einfach ist:
short s = 1;
s = s + s; <- Compiling error
//possible loss of precision
// required: short
// found: int
Dies erfordert ein Gießen mit einem möglichen Präzisionsverlust.
Gleiches gilt für die Gleitkommaoperatoren
Wenn mindestens einer der Operanden eines numerischen Operators vom Typ double ist, wird die Operation unter Verwendung einer 64-Bit-Gleitkomma-Arithmetik ausgeführt, und das Ergebnis des numerischen Operators ist ein Wert vom Typ double. Wenn der andere Operand kein Double ist, wird er zuerst erweitert (§5.1.5), um double durch numerische Heraufstufung einzugeben (§5.6).
Die Promotion erfolgt also auf dem Float in Double.
Und die Mischung aus ganzzahligem und gleitendem Wert führt wie gesagt zu gleitenden Werten
Wenn mindestens einer der Operanden eines binären Operators vom Gleitkomma-Typ ist, ist die Operation eine Gleitkomma-Operation, selbst wenn der andere ganzzahlig ist.
Dies gilt für Binäroperatoren, jedoch nicht für "Zuweisungsoperatoren" wie +=
Ein einfaches Arbeitsbeispiel reicht aus, um dies zu beweisen
int i = 1;
i += 1.5f;
Der Grund ist, dass hier eine implizite Besetzung erfolgt, die wie folgt ausgeführt wird
i = (int) i + 1.5f
i = (int) 2.5f
i = 2
1 und 3 sind integer und Inhalte auch so Java tut , eine ganze Zahl ist , die das Ergebnis 0. Wenn Sie doppelt Konstanten , die Sie schreiben müssen schreiben wollen 1.0
und 3.0
.
Die einfachste Lösung besteht darin, dies einfach zu tun
double g = ((double) 1 / 3);
Da Sie 1.0 / 3.0 nicht eingegeben haben, können Sie es manuell in den Datentyp double konvertieren, da Java davon ausgegangen ist, dass es sich um eine Ganzzahldivision handelt, und dies auch dann, wenn dies eine Einschränkung der Konvertierung bedeutet. Dies wird als Cast-Operator bezeichnet.
Ich war das.
double g = 1.0/3.0;
System.out.printf("%gf", g);
Verwenden Sie .0, wenn Sie doppelte Berechnungen durchführen, oder Java geht davon aus, dass Sie Ganzzahlen verwenden. Wenn eine Berechnung eine beliebige Anzahl von Doppelwerten verwendet, ist die Ausgabe ein Doppelwert. Wenn alle Ganzzahlen sind, ist die Ausgabe eine Ganzzahl.
(1/3) bedeutet ganzzahlige Division, deshalb können Sie aus dieser Division keinen Dezimalwert erhalten. Um dieses Problem zu lösen, verwenden Sie:
public static void main(String[] args) {
double g = 1.0 / 3;
System.out.printf("%.2f", g);
}
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
Da sowohl 1 als auch 3 Ints sind, wird das Ergebnis nicht gerundet, sondern abgeschnitten. Sie ignorieren also Brüche und nehmen nur Ganzes.
Um dies zu vermeiden, haben Sie mindestens eine Ihrer Zahlen 1 oder 3 als Dezimalform 1.0 und / oder 3.0.
Probieren Sie es aus:
public static void main(String[] args) {
double a = 1.0;
double b = 3.0;
double g = a / b;
System.out.printf(""+ g);
}
Mach "double g = 1.0 / 3.0;" stattdessen.
Viele andere haben es versäumt, auf das eigentliche Problem hinzuweisen:
Eine Operation nur für Ganzzahlen wandelt das Ergebnis der Operation in eine Ganzzahl um.
Dies bedeutet zwangsläufig, dass Gleitkommaergebnisse, die als Ganzzahl angezeigt werden könnten , abgeschnitten werden (den Dezimalteil abschneiden).
Was ist Casting (Typumwandlung / Typkonvertierung), das Sie fragen?
Es hängt von der Implementierung der Sprache ab, aber Wikipedia hat eine ziemlich umfassende Sichtweise und es geht auch um Zwang , der eine wichtige Information bei der Beantwortung Ihrer Frage ist.
1/2
, nicht in der Zielsprache (Java). Sie rufen einfach eine Ganzzahldivision auf, die zu einem Ganzzahlergebnis führt. Das Type Casting ist nur auf die Aufwärtskonvertierung von a int
zu double
während der Zuordnung zurückzuführen.
0.5
. In Java 1/2
handelt es sich einfach um eine Ganzzahldivision, die zu einer Ganzzahl von Null führt. Sie können einem Double eine Null zuweisen, es ist immer noch eine Null, wenn auch ein 0.0
Double.
int i = .99999999
setzt int auf 0. Insbesondere nimmt es den ganzzahligen Teil und verwirft den Rest.