Ich nehme an dem Unterschied ist eine Umstellung von einem 80-Bit-Gleitkomma-Wert auf einen lang vs einer Umwandlung von einem 80-Bit-Gleitkomma-Wert in eine 64-Bit und eine dann eine Umwandlung in eine lang.
(Der Grund für die 80 Bits überhaupt kommen, ist, dass, dass eine typische Genauigkeit ist für die eigentliche Arithmetik verwendet, und die Breite der Gleitkommaregister.)
das Ergebnis 80-Bit Angenommen, so etwas wie 10,999999999999999 ist - die Umwandlung von diesem zu einer langen Renditen 10. Jedoch ist der nächste 64-Bit-Gleitkommawert zu dem 80-Bit-Wert tatsächlich 11,0, so endet die zweistufige Umwandlung bis ergibt 11.
EDIT: Um dies zu geben a etwas mehr Gewicht ...
Hier ist ein Java-Programm, das Arithmetik mit beliebiger Genauigkeit verwendet, um das zu tun die Berechnung. Beachten Sie, dass der Doppelwert, der 0,1 am nächsten liegt, in BigDecimal konvertiert wird. Dieser Wert ist 0,10000000000000000555511151231257827021181583404541015625. (Mit anderen Worten, das genaue Ergebnis der Berechnung ist nicht 11 sowieso.)
import java.math.*;
public class Test
{
public static void main(String[] args)
{
BigDecimal c = new BigDecimal(0.1d);
BigDecimal a = new BigDecimal(1d);
BigDecimal b = new BigDecimal(2d);
BigDecimal result = b.subtract(a)
.add(c)
.divide(c, 40, RoundingMode.FLOOR);
System.out.println(result);
}
}
Hier ist das Ergebnis:
10.9999999999999994448884876874217606030632
Mit anderen Worten, dass bis etwa 40 Dezimalstellen korrekt ist (Art und Weise mehr als entweder 64 oder 80 Bit Fließkomma verarbeiten kann).
Betrachten wir nun, wie diese Zahl im Binärformat aussieht. Ich habe keine Werkzeuge, um die Konvertierung leicht durchzuführen, aber wieder können wir Java verwenden, um zu helfen. Unter der Annahme einer normalisierten Zahl endet der Teil "10" mit drei Bits (eine weniger als für elf = 1011). Das hinterlässt 60 Bits Mantisse für erweiterte Präzision (80 Bits) und 48 Bits für doppelte Präzision (64 Bits).
Also, was ist die nächste Nummer 11 in jeder Genauigkeit? Auch hier wollen wir Java verwenden:
import java.math.*;
public class Test
{
public static void main(String[] args)
{
BigDecimal half = new BigDecimal("0.5");
BigDecimal eleven = new BigDecimal(11);
System.out.println(eleven.subtract(half.pow(60)));
System.out.println(eleven.subtract(half.pow(48)));
}
}
Ergebnisse: So
10.999999999999999999132638262011596452794037759304046630859375
10.999999999999996447286321199499070644378662109375
, die drei Zahlen, die wir haben, sind:
Correct value: 10.999999999999999444888487687421760603063...
11-2^(-60): 10.999999999999999999132638262011596452794037759304046630859375
11-2^(-48): 10.999999999999996447286321199499070644378662109375
nun den nächsten Wert auf die richtige trainieren für jede Genauigkeit - für erweiterte Präzision ist es weniger als 11. Runden Sie jeden dieser Werte zu einem langen, und Sie am Ende mit 10 und 11 jeweils.
Hoffentlich ist dies genug Beweise, die Zweifler zu überzeugen;)
sie sind die gleichen (beide 11) auf meinem System? –
mit was kompilierst du das? – Joseph
Nur zum Spaß, versuchen Sie, eine lokale Variable zu machen und sehen Sie, ob das die Dinge ändert. –