Ich habe diesen Code geschrieben:
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
Das Ergebnis ist 0. Warum ist das so und wie löse ich dieses Problem?
quelle
Ich habe diesen Code geschrieben:
public static void main(String[] args) {
double g = 1 / 3;
System.out.printf("%.2f", g);
}
Das Ergebnis ist 0. Warum ist das so und wie löse ich dieses Problem?
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...
.
int i = .99999999
setzt int auf 0. Insbesondere nimmt es den ganzzahligen Teil und verwirft den Rest.DOWN
gegen Null. Die RundungFLOOR
geht in Richtung negative Unendlichkeit.1/3
verwendet die Ganzzahldivision, da beide Seiten Ganzzahlen sind.Sie brauchen mindestens einen von ihnen zu sein
float
oderdouble
.Wenn Sie die Werte wie in Ihrer Frage in den Quellcode eingeben, können Sie dies tun
1.0/3
. Das1.0
ist ein Doppel.Wenn Sie die Werte von einer anderen Stelle erhalten, können Sie sie in eine
(double)
verwandeln .int
double
quelle
Wirken Sie es explizit als
double
Dies liegt daran, dass Java die Ganzzahldivisionsoperation für
1
und verwendet,3
da Sie sie als Ganzzahlkonstanten eingegeben haben.quelle
du solltest benutzen
oder
Die Ganzzahldivision gibt eine Ganzzahl zurück.
quelle
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
/ istfloat
, findet eine Gleitkomma-Arithmetik statt. Aber Sie werden das gleiche Problem haben, wenn Sie das tun:quelle
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:
quelle
Machen Sie die 1 zu einem Float und es wird eine Float-Division verwendet
quelle
Die Konvertierung in JAVA ist recht einfach, erfordert jedoch etwas Verständnis. Wie im JLS für ganzzahlige Operationen erläutert :
Und ein Beispiel ist immer der beste Weg, um das JLS zu übersetzen;)
Ein kleines Beispiel mit Eclipse zeigt, dass selbst das Hinzufügen von zwei
short
s nicht so einfach ist:Dies erfordert ein Gießen mit einem möglichen Präzisionsverlust.
Gleiches gilt für die Gleitkommaoperatoren
Die Promotion erfolgt also auf dem Float in Double.
Und die Mischung aus ganzzahligem und gleitendem Wert führt wie gesagt zu gleitenden Werten
Dies gilt für Binäroperatoren, jedoch nicht für "Zuweisungsoperatoren" wie
+=
Ein einfaches Arbeitsbeispiel reicht aus, um dies zu beweisen
Der Grund ist, dass hier eine implizite Besetzung erfolgt, die wie folgt ausgeführt wird
quelle
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
und3.0
.quelle
Die einfachste Lösung besteht darin, dies einfach zu tun
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.
quelle
Ich war das.
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.
quelle
(1/3) bedeutet ganzzahlige Division, deshalb können Sie aus dieser Division keinen Dezimalwert erhalten. Um dieses Problem zu lösen, verwenden Sie:
quelle
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.
quelle
Probieren Sie es aus:
quelle
Mach "double g = 1.0 / 3.0;" stattdessen.
quelle
Viele andere haben es versäumt, auf das eigentliche Problem hinzuweisen:
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.
http://en.wikipedia.org/wiki/Type_conversion
quelle
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 aint
zudouble
während der Zuordnung zurückzuführen.0.5
. In Java1/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 ein0.0
Double.