为什么Double.parseDouble使9999999999999999变为10000000000000000?

为什么Double.parseDouble使9999999999999999变为10000000000000000 ? 例如 :

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

IS打印

 10000000000000000 

相反,它必须显示99999999999999999999999999999999.00

非常感谢任何forms的帮助。

double只有15/16位数的精度,当你给它一个它不能代表的数字(大多数时候,即使0.1不准确)它需要最接近的可表示数字。

如果要准确表示9999999999999999 ,则需要使用BigDecimal。

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

版画

 9999999999999999 

很少有真实世界的问题需要这种准确性,因为无论如何你都无法准确地测量任何东西。 即每个quintillion的误差为1份。


你可以找到最大的可表示整数

 // 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; } } 

版画

 Cannot represent 9007199254740993 was 9.007199254740992E15 

最大可表示的整数是9007199254740992,因为它需要少一位(因为它的偶数)

数字9999999999999999刚好高于双精度浮点的精度限制。 换句话说,53位尾数无法容纳9999999999999999

因此结果是它舍入到最接近的双精度值 – 即10000000000000000

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

9999999999999999需要54位尾数以便精确表示,而double只有52位。因此,数字四舍五入到可以使用52位尾数表示的最接近的数字。 这个数字恰好是10000000000000000

10000000000000000需要更少位的原因是它的二进制表示以很多零结束,并且这些零可以通过增加(二进制)指数来表示。

有关类似问题的详细解释,请参阅为什么(长)9223372036854665200d给我9223372036854665216?