Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么Double.parseDouble的值是9999999999999999到100000000000000?_Java_Double - Fatal编程技术网

Java 为什么Double.parseDouble的值是9999999999999999到100000000000000?

Java 为什么Double.parseDouble的值是9999999999999999到100000000000000?,java,double,Java,Double,为什么Double.parseDouble将999999999999转换为100000000000000? 例如: Double d =Double.parseDouble("9999999999999999"); String b= new DecimalFormat("#.##").format(d); System.out.println(b); 正在印刷 10000000000000000 相反,它必须显示999999999999或999999999999.00 非常感谢任何帮助。数

为什么Double.parseDouble将
999999999999
转换为
100000000000000
? 例如:

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

10000000000000000
相反,它必须显示
999999999999
999999999999.00


非常感谢任何帮助。

数字
99999999999999
刚好高于双精度浮点的精度限制。换句话说,53位尾数不能容纳
9999999999999

因此,结果是将其四舍五入到最接近的双精度值,即
100000000000000

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

999999999999
需要54位尾数才能准确表示,而
double
只有52位尾数。因此,该数字被四舍五入到可以使用52位尾数表示的最接近的数字。这个数字正好是
100000000000000

 9999999999999999 = 0x2386f26fc0ffff  // 54 significant bits needed
10000000000000000 = 0x2386f26fc10000  // 38 significant bits needed
100000000000000
需要更少的位的原因是它的二进制表示以大量的零结尾,这些零可以通过增加(二进制)指数来表示


有关类似问题的详细解释,请参见

double
的精度只有15/16位,当您给它一个无法表示的数字时(大多数情况下,即使0.1也不准确),它会取最接近的可表示数字

如果要准确地表示
9999999999999
,则需要使用BigDecimal

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

9999999999999999
Cannot represent 9007199254740993 was 9.007199254740992E15
现实世界中很少有问题需要这种精确性,因为你无论如何都无法如此精确地测量任何东西。i、 e.误差为每五分之一


您可以使用

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

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

+1:正是这一点。表示无符号99999999999999999需要54位,标准双精度中的最大值是9007199254740991。@DonalFellows它不是偶数吗?如果可以表示9007199254740991,则必须同时表示9007199254740992。@Peter:0x1FFFFFFFFFFFFFFFF是一个奇数,至少需要53位来表示。大于1的数字需要54位(或指数)。猜猜那个十进制值是多少?:-)从技术上讲,您可以表示任何不超过53个有效位(且不会溢出)的大整数。所以
2^128
是一个整数,可以表示为
double
。但是
9007199254740991
9007199254740992
是最后一个连续整数,可以用双精度表示。@donalvellows,9007199254740991+1是偶数,所以它只需要53位,因为最后一位(为零)可以隐含。9007199254740991+2是奇数,需要54位。浮点运算——1985年以来计算机科学的最大谜团在考虑正常IEEE双精度运算时,使用二进制运算比使用某种十进制近似更有用。9007199254740992=200000000000000(十六进制)这就是为什么我只考虑2的幂。