2012-01-18 5 views
16

¿por qué Double.parseDoble hace 9999999999999999 a 10000000000000000? Por ejemplo:¿por qué Double.parseDoble hace 9999999999999999 a 10000000000000000?

Double d =Double.parseDouble("9999999999999999"); 
String b= new DecimalFormat("#.##").format(d); 
System.out.println(b); 

está imprimiendo

10000000000000000 

su lugar, ha de mostrar 9999999999999999 o 9999999999999999.00

Cualquier tipo de ayuda es muy apreciada.

+11

aritmética de coma flotante --- el mayor misterio de la ciencia de la computación desde 1985 – subsub

Respuesta

12

double sólo tiene 15/16 de dígitos de precisión y cuando usted le da un número que no puede representar (que es la mayoría de las veces, incluso es 0,1 no es exacto) toma el número representable más cercano.

Si quiere representar exactamente 9999999999999999, necesita usar BigDecimal.

BigDecimal bd = new BigDecimal("9999999999999999"); 
System.out.println(new DecimalFormat("#.##").format(bd)); 

impresiones

9999999999999999 

muy pocos problemas del mundo real necesitan esta precisión porque no se puede medir con precisión esta nada de todos modos. es decir, a un error de 1 parte por quintillón.


puede encontrar el mayor entero representable con

// search all the powers of 2 until (x + 1) - x != 1 
for (long l = 1; l > 0; l <<= 1) { 
    double d0 = l; 
    double d1 = l + 1; 
    if (d1 - d0 != 1) { 
     System.out.println("Cannot represent " + (l + 1) + " was " + d1); 
     break; 
    } 
} 

impresiones

Cannot represent 9007199254740993 was 9.007199254740992E15 

El mayor entero representable es 9007199254740992, ya que necesita una menos bits (como su par)

+1

Es mucho más útil usar la aritmética binaria cuando se piensa en dobles IEEE normales que usar algún tipo de aproximación decimal. –

+0

9007199254740992 = 20000000000000 (hexadecimal) = 100000000000000000000000000000000000000000000000000000 (bin) –

+0

@DonalFellows Cierto, es por eso que solo considero poderes de 2. –

15

El número 9999999999999999 está justo por encima del límite de precisión de coma flotante de doble precisión. En otras palabras, la mantisa de 53 bits no puede contener 9999999999999999.

El resultado es que se redondea al valor de precisión doble más cercano, que es 10000000000000000.

9999999999999999 = 0x2386f26fc0ffff // 54 significant bits needed 
10000000000000000 = 0x2386f26fc10000 // 38 significant bits needed 
+0

+1: Precisamente esto. Se necesitan _54_ bits para representar un 9999999999999999 sin signo y el valor más grande que cabrá exactamente en un doble estándar es 9007199254740991. –

+0

@DonalFellows ¿No sería un número par?Si se puede representar 9007199254740991, debe representarse también 9007199254740992. –

+0

@ Peter: 0x1fffffffffffff es un número impar que requiere un mínimo de 53 bits para representar. El número uno más grande requiere 54 bits (o un exponente). ¿Adivina cuál es ese valor en decimal? :-) –

5

9999999999999999 requiere 54 bits de mantisa con el fin de ser representado exactamente, y double sólo tiene 52. Por consiguiente, el número se redondea al número más cercano que puede ser representadas usando una mantisa de 52 bits. Este número es 10000000000000000.

El motivo 10000000000000000 requiere menos bits es que su representación binaria termina en muchos ceros, y esos ceros pueden representarse aumentando el exponente (binario).

Para una explicación detallada de un problema similar, consulte Why is (long)9223372036854665200d giving me 9223372036854665216?