小数显示双重精度的损失

发布于 2025-02-02 06:54:18 字数 415 浏览 3 评论 0原文

为什么显示以下值会差异?

double x = (double)988530483551494912L;
System.out.printf("%f%n", x);           -> 988530483551494910.000000
System.out.println(Double.toString(x)); -> 9.8853048355149491E17
System.out.println(new BigDecimal(x));  -> 988530483551494912

如您所见,toString()%f转换失去了最后一位数字的精度。但是,我们可以看到最后一个数字实际上是精确的,因为bigdecimal转换保留了它。

Why is there a discrepancy in the display of the following value?

double x = (double)988530483551494912L;
System.out.printf("%f%n", x);           -> 988530483551494910.000000
System.out.println(Double.toString(x)); -> 9.8853048355149491E17
System.out.println(new BigDecimal(x));  -> 988530483551494912

As you can see, both toString() and the %f conversion lose the precision of the last digit. However, we can see that the last digit is actually precise, because the BigDecimal conversion preserves it.

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

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

发布评论

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

评论(1

夏见 2025-02-09 06:54:18

感谢 @user16320675的评论,我要回答自己的问题。原因是数字988530483551494912L具有超过double> double键入精度的限制的精度,并且double.toString() >%f),根据文档,仅使用最小数字数量,将double数字与相邻数字区分开。相邻的数字是与原始的两侧具有最小代表性差异的数字。

可以使用MATH.Nextafter显示相邻数字:

import static java.lang.Math.nextAfter;
double x = (double)988530483551494912;
System.out.println(nextAfter(x, Double.MIN_VALUE));  ==> 9.8853048355149478E17
System.out.println(x);                               ==> 9.8853048355149491E17
System.out.println(nextAfter(x, Double.MAX_VALUE));  ==> 9.8853048355149504E17

因此,添加任何更重要的数字没有意义来自相邻的值。

但是,仍然存在一个问题:它显示了17个重要数字,但16个就足够了。我不确定为什么会发出额外的最终数字。

Thanks to @user16320675's comment, I'm answering my own question. The reason is that the number 988530483551494912L has precision beyond the limit of the double type's precision, and Double.toString() (and similarly %f) will, as per documentation, only use the minimum number of significant digits required to distinguish a double number from adjacent numbers. Adjacent numbers are those that have the smallest representable difference from the original, on either side of it.

This can be demonstrated using Math.nextAfter to show the adjacent numbers:

import static java.lang.Math.nextAfter;
double x = (double)988530483551494912;
System.out.println(nextAfter(x, Double.MIN_VALUE));  ==> 9.8853048355149478E17
System.out.println(x);                               ==> 9.8853048355149491E17
System.out.println(nextAfter(x, Double.MAX_VALUE));  ==> 9.8853048355149504E17

So, as we can see, there is no point in adding any more significant figures because this string representation already has enough digits to distinguish the number from adjacent values.

However, a question still remains: it shows 17 significant figures, but 16 would be sufficient. I'm not sure why it issues an extra final digit.

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