为什么是Double.parseDouble制作9999999999999999到10000000000000000?例如 :
Double d =Double.parseDouble("9999999999999999");
String b= new DecimalFormat("#.##").format(d);
System.out.println(b);
Run Code Online (Sandbox Code Playgroud)
IS打印
10000000000000000
Run Code Online (Sandbox Code Playgroud)
相反,它必须显示9999999999999999或9999999999999999.00
非常感谢任何形式的帮助.
Mys*_*ial 16
该数字9999999999999999刚好高于双精度浮点的精度限制.换句话说,53位尾数无法保持9999999999999999.
因此结果是它被四舍五入到最接近的双精度值 - 即10000000000000000.
9999999999999999 = 0x2386f26fc0ffff // 54 significant bits needed
10000000000000000 = 0x2386f26fc10000 // 38 significant bits needed
Run Code Online (Sandbox Code Playgroud)
Pet*_*rey 13
double 只有15/16位数的精度,当你给它一个它不能代表的数字(大多数情况下,即使0.1不准确)它需要最接近的可表示数字.
如果要9999999999999999准确表示,则需要使用BigDecimal.
BigDecimal bd = new BigDecimal("9999999999999999");
System.out.println(new DecimalFormat("#.##").format(bd));
Run Code Online (Sandbox Code Playgroud)
版画
9999999999999999
Run Code Online (Sandbox Code Playgroud)
很少有真实世界的问题需要这种准确性,因为无论如何你都无法准确地测量任何东西.即每个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;
}
}
Run Code Online (Sandbox Code Playgroud)
版画
Cannot represent 9007199254740993 was 9.007199254740992E15
Run Code Online (Sandbox Code Playgroud)
最大可表示的整数是9007199254740992,因为它需要少一位(因为它的偶数)
9999999999999999需要54位尾数才能准确表示,并且double只有52位.因此,数字四舍五入到可以使用52位尾数表示的最接近的数字.这个号码恰好是10000000000000000.
10000000000000000需要较少位的原因是它的二进制表示以很多零结尾,并且这些零可以通过增加(二进制)指数来表示.
有关类似问题的详细解释,请参阅为什么(长)9223372036854665200d给我9223372036854665216?