浮点运算不能产生精确的结果

2022-01-09 00:00:00 floating-point java

我需要在Java中做一些浮点运算,如下代码所示:

I need to do some floating point arithmetic in Java as shown in the code below:

public class TestMain {
    private static Map<Integer, Double> ccc = new HashMap<Integer, Double>() {
      { put(1, 0.01); put(2, 0.02); put(3, 0.05); put(4, 0.1); put(6, 0.2);
        put(10, 0.5); put(20, 1.0); put(30, 2.0); put(50, 5.0); put(100, 10.0);
      }
    };

    Double increment(Double i, boolean up) {
        Double inc = null;

        while (inc == null) {
            inc = ccc.get(i.intValue());

            if (up)
                --i;
            else
                ++i;
        }
        return inc;
    }

    public static void main(String[] args) {
        TestMain tt = new TestMain();

        for (double i = 1; i < 1000; i += tt.increment(i, true)) {
            System.out.print(i + ",");
        }
    }
}

这是为了模拟 Betfair 输出的值范围微调器小部件.

Java 中的浮点运算似乎引入了一些意想不到的错误.例如,我得到 2.180000000000001 而不是 2.18.浮点数有什么用,你不能相信对它们执行的算术结果?我该如何解决这个问题?

Floating point arithmetic in Java seems to introduce some unexpected errors. For example, I get 2.180000000000001 instead of 2.18. What use are floating point numbers is you can't trust the results of arithmetic performed on them? How can I get around this issue?

推荐答案

如果你需要精确的十进制值,你应该使用java.math.BigDecimal.然后阅读每个计算机科学家应该了解的浮点运算知识"了解您获得这些结果的背景.

If you need exact decimal values, you should use java.math.BigDecimal. Then read "What Every Computer Scientist Should Know About Floating-Point Arithmetic" for the background of why you're getting those results.

(我有一篇 .NET 中心文章,您可能会发现它更容易阅读- 当然更短.Java 和 .NET 之间的差异对于理解这个问题来说几乎是无关紧要的.)

(I have a .NET-centric article which you may find easier to read - and certainly shorter. The differences between Java and .NET are mostly irrelevant for the purposes of understanding this issue.)

相关文章