2013-08-11 5 views
7

ich diesen Code habe jetztErste unerwartete Ergebnisse, wenn Typumwandlung zwischen langen und Doppel

public class LimitTest{ 
    public static void main(String[] args){ 
     long l; 
     double d; 
     l = 9223372036854775807L;// The largest number a long can hold. 
     d = l; 
     System.out.println(l); 
     System.out.println(d); 
     System.out.println(l == d); 
    } 
} 

, das Ergebnis es produziert, ist ein bisschen unerwartet, aber wieder, ich bin nicht sehr mit Typkonvertierungen erlebt.

Ausgabe

9223372036854775807 
9.223372036854776E18 
true 

Nun werden die beiden gedruckten Zahlen sind eindeutig UNGLEICH, also warum tut l == d Rückkehr true?

Antwort

5

Die Variablen l und d haben verschiedene Arten, so long == double der Ausdruck den long auf eine double wirft ...

P. S. l ist ein schlechter Variablenname imho, da es bei einem Blick auf Code sehr ähnlich aussieht wie 1.

2

so, warum ich nicht == d true zurück ;

Da long vor dem Vergleich in double konvertiert wird. Und daher ist das Ergebnis wahr.

Dies wird in JLS - Section 5.6.2 angegeben: angelegt

Widening primitive Umwandlung (§5.1.2) entweder eines oder beide Operanden zu konvertieren, wie durch die folgenden Regeln festgelegt:

  • Wenn entweder Operand vom Typ double wird der andere in double umgewandelt.

Sie sehen anderes Ergebnis für double, weil nicht alle long Werte durch einen eindeutigen double Wert dargestellt werden kann. Möglicherweise haben Sie also viele doppelte Werte für einen einzelnen langen Wert. Es gibt einen möglichen Präzisionsverlust während der Umwandlung von long zu double.

Von JLS Section 5.1.2:

Eine Verbreiterung Umwandlung eines int oder long-Wert zu schweben, oder eines langen Wert zu verdoppeln, in Genauigkeitsverlust führen kann - das heißt, kann das Ergebnis verlieren einige der am wenigsten signifikanten Bits des Werts.

2

Um zwei Werte zu vergleichen, müssen sie denselben Typ haben. Hier wird der long-Wert implizit in den double-Typ konvertiert, und das Ergebnis der Konvertierung ergibt den gleichen Wert wie eine Zuweisung.

Die Werte unterscheiden sich in erster Linie, weil der Doppeltyp weniger "Signifikanz" hat (er hat eine 53-Bit-Mantisse für die Speicherung der tatsächlichen Ziffern; der Rest der Bits wird für das Vorzeichen und den Exponenten verwendet) als lang (alle 64 Bits). Nicht alle langen Werte können als ein eindeutiger Doppelwert dargestellt werden.

2

9223372036854775807 und 9.223372036854776E18gleich

Beachten Sie die ersten 15 Ziffern der Präzision 922337203685477 gleich sind. Der Rest der ersten Nummer 5807 wird auf eine 6 gerundet, so dass die E18 angehängt werden kann.

9223372036854775807 in wissenschaftlicher Notation ist:

9.223372036854775807 x 10^18 == 9.223372036854775807E18 

vergleichen:

9.223372036854775807E18 
9.223372036854776E18 

Der Wert mit mehr Genauigkeit gespeichert wird, als es mit, sehen dies für den Nachweis angezeigt:

long l; 
    double d; 
    l = Long.MAX_VALUE;// The largest number a long can hold. 
    d = l; //This is implicitly cast to (double) 
    System.out.println("long: " + l); 
    System.out.println("double: " + d); 
    System.out.println("double back to long: " + (long) d); 

lang: 9223372036854775807
double: 9.223372036854776E18
doppelt zurück zu lang: 9223372036854775807

Es gibt auch die sekundäre Frage der ist, wie floats und doubles gespeichert sind. Während Integer-Typen (Byte, Short, Int, Long) genau sind, verwenden float und double den IEEE754-Mantissen-Exponenten-Stil, der es ihnen ermöglicht, einen größeren Zahlenbereich darzustellen, jedoch mit geringerer Genauigkeit. http://en.wikipedia.org/wiki/IEEE_754-1985

Verwandte Themen