java - 为什么两个名义上具有相同值的浮点结果不同?

标签 java floating-point

我最近在阅读有关在内存中存储浮点值的内容。我写了一个小程序来测试我读过的内容。我注意到 Java 处理浮点值的方式有所不同。

public class Test
{
   public static void main(String args[])
   {
     double a = 0.90;
     System.out.println(a);
     System.out.println(2.00-1.10);
   }
 }

以上程序正在打印

0.9
0.8999999999999999

为什么这两个语句打印的值不同?我知道有些 float 值无法准确表示。在这种情况下,两者应该给出相同的值。

最佳答案

Why both these statements are not printing the same value?

结果不一样。

I know some floating values can't be represented exactly.

因此您应该假设操作的结果可能取决于您使用的值的表示误差量。

for (long l = 1; l <= 1e16; l *= 10) {
    double a = l + 2;
    double b = l + 1.1;
    System.out.println(a + " - " + b + " is " + (a - b));
}

随着值变大表示误差变大,与0.9的结果相比变大

3.0 - 2.1 is 0.8999999999999999
12.0 - 11.1 is 0.9000000000000004
102.0 - 101.1 is 0.9000000000000057
1002.0 - 1001.1 is 0.8999999999999773
10002.0 - 10001.1 is 0.8999999999996362
100002.0 - 100001.1 is 0.8999999999941792
1000002.0 - 1000001.1 is 0.9000000000232831
1.0000002E7 - 1.00000011E7 is 0.900000000372529
1.00000002E8 - 1.000000011E8 is 0.9000000059604645
1.000000002E9 - 1.0000000011E9 is 0.8999999761581421
1.0000000002E10 - 1.00000000011E10 is 0.8999996185302734
1.00000000002E11 - 1.000000000011E11 is 0.899993896484375
1.000000000002E12 - 1.0000000000011E12 is 0.9000244140625
1.0000000000002E13 - 1.00000000000011E13 is 0.900390625
1.00000000000002E14 - 1.000000000000011E14 is 0.90625
1.000000000000002E15 - 1.0000000000000011E15 is 0.875
1.0000000000000002E16 - 1.0000000000000002E16 is 0.0

以及关于表示错误何时变得如此之大,您的操作什么都不做的话题。

for (double d = 1; d < Double.MAX_VALUE; d *= 2) {
    if (d == d + 1) {
        System.out.println(d + " + 1 == " + (d + 1));
        break;
    }
}
for (double d = 1; d < Double.MAX_VALUE; d *= 2) {
    if (d == d - 1) {
        System.out.println(d + " - 1 == " + (d - 1));
        break;
    }
}

打印

9.007199254740992E15 + 1 == 9.007199254740992E15
1.8014398509481984E16 - 1 == 1.8014398509481984E16

关于java - 为什么两个名义上具有相同值的浮点结果不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13160583/

相关文章:

java - JASIG CAS 证书

java - 如何根据 Java 中的 Schematron 模式验证文档?

Itextpdf 库教程上的 java.io.FileNotFoundException

C# 值比较

java - 调整窗口大小后,四边形的缩放不正确。怎么修?

java - 如何安装aparapi

c++ - 这段获取最低位位置的代码是如何工作的?

c - 处理单精度和 double 浮点的 C 代码的正确设计?

linux - 有什么方法可以确保浮点运算结果在 linux 和 windows 中相同

string - Python 硬编码字符串与 str() 方法之间的差异