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

发布于 2024-12-27 17:42:46 字数 405 浏览 3 评论 0原文

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

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

IS 打印

10000000000000000

必须显示 99999999999999999999999999999999.00

非常感谢任何类型的帮助。

why is the Double.parseDouble making 9999999999999999 to 10000000000000000 ?
For Example :

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

IS Printing

10000000000000000

instead it has to show 9999999999999999 or 9999999999999999.00

Any sort of help is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

内心激荡 2025-01-03 17:42:46

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

因此结果是四舍五入到最接近的双精度值 - 即 10000000000000000

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

The number 9999999999999999 is just above the precision limit of double-precision floating-point. In other words, the 53-bit mantissa is not able to hold 9999999999999999.

So the result is that it is rounded to the nearest double-precision value - which is 10000000000000000.

 9999999999999999 = 0x2386f26fc0ffff  // 54 significant bits needed
10000000000000000 = 0x2386f26fc10000  // 38 significant bits needed
我还不会笑 2025-01-03 17:42:46

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

如果你想准确地表示9999999999999999,你需要使用BigDecimal。

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

double only has 15/16 digits of accuracy and when you give it a number it can't represent (which is most of the time, even 0.1 is not accurate) it takes the closest representable number.

If you want to represent 9999999999999999 exactly, you need to use BigDecimal.

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

prints

9999999999999999

Very few real world problems need this accuracy because you can't measure anything this accurately anyway. i.e. to an error of 1 part per quintillion.


You can find the largest representable integer with

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

prints

Cannot represent 9007199254740993 was 9.007199254740992E15

The largest representable integer is 9007199254740992 as it needs one less bit (as its even)

影子是时光的心 2025-01-03 17:42:46

9999999999999999 需要 54 位尾数才能准确表示,而 double 只有 52 位。因此,该数字将四舍五入为最接近的数字。 > 使用 52 位尾数表示。这个数字恰好是10000000000000000

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

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

9999999999999999 requires 54 bits of mantissa in order to be represented exactly, and double only has 52. The number is therefore rounded to the nearest number that can be represented using a 52-bit mantissa. This number happens to be 10000000000000000.

The reason 10000000000000000 requires fewer bits is that its binary representation ends in a lot of zeroes, and those zeroes can get represented by increasing the (binary) exponent.

For detailed explanation of a similar problem, see Why is (long)9223372036854665200d giving me 9223372036854665216?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文