为什么Double.parseDouble 9999999999999999到1000000000000000000?

2022-09-02 20:24:57

为什么 Double.parseDouble 要制作 ?例如:999999999999999910000000000000000

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

IS 打印

10000000000000000

相反,它必须显示或99999999999999999999999999999999.00

非常感谢任何形式的帮助。


答案 1

该数字刚好高于双精度浮点的精度限制。换句话说,53位尾数无法保持 。99999999999999999999999999999999

因此,结果是它被舍入到最接近的双精度值 - 即 。10000000000000000

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

答案 2

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

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

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

指纹

9999999999999999

很少有现实世界的问题需要这种准确性,因为无论如何你都无法如此准确地测量任何东西。即每万亿分之一的误差。


您可以找到最大可表示整数

// 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因为它需要少一位(因为它的偶数)


推荐