Java:使用双精度不准确

Mar*_*kka 5 java floating-point double

可能重复:在Java程序中使用Java中的
双精度保留精度
奇怪的浮点行为

我正在制作直方图课程,我遇到了一个奇怪的问题.

以下是该类的基础知识,有更多方法,但它们与问题无关.

private int[] counters;
private int numCounters;
private double min, max, width;

public Histogram(double botRange, double topRange, int numCounters) {
    counters = new int[numCounters];
    this.numCounters = numCounters;
    min = botRange;
    max = topRange;
    width = (max - min) / (double) numCounters;
}

public void plotFrequency() {
    for (int i = 0; i < counters.length; i++) {
        writeLimit(i * width, (i + 1) * width);
        System.out.println(counters[i]);
    }
}

private void writeLimit(double start, double end) {
    System.out.print(start + " <= x < " + end + "\t\t");
}
Run Code Online (Sandbox Code Playgroud)

当我绘制频率时会出现问题.我创建了2个实例.新直方图(0,1,10); 新的直方图(0,10,10);

这就是他们的输出.

Frequecy
0.0 <= x < 0.1      989
0.1 <= x < 0.2      1008
0.2 <= x < 0.30000000000000004      1007
0.30000000000000004 <= x < 0.4      1044
0.4 <= x < 0.5      981
0.5 <= x < 0.6000000000000001       997
0.6000000000000001 <= x < 0.7000000000000001        1005
0.7000000000000001 <= x < 0.8       988
0.8 <= x < 0.9      1003
0.9 <= x < 1.0      978

Frequecy
0.0 <= x < 1.0      990
1.0 <= x < 2.0      967
2.0 <= x < 3.0      1076
3.0 <= x < 4.0      1048
4.0 <= x < 5.0      971
5.0 <= x < 6.0      973
6.0 <= x < 7.0      1002
7.0 <= x < 8.0      988
8.0 <= x < 9.0      1003
9.0 <= x < 10.0     982    
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,为什么我在第一个例子中获得了非常长的小数限制,而不是第二个?

ami*_*mit 5

双打不准确.

这是因为有无限可能的实数和只有有限数量的位来表示这些数字.

看看:每个程序员应该了解浮点运算


cor*_*iKa 3

有些小数不能用 double 值精确表示。0.3 是这些值之一。

所有小于某个数字(我忘记了哪个)的整数值碰巧都有一个双精度值的精确表示,因此您看不到近似值。

考虑一下我们如何看待数字:数字 123 表示为 (1 * 100) + (2 * 10) + (3 * 1)。我们使用 10 作为基数。二进制数使用两个。那么,当您查看一个数字的分数时,如何通过将 2 的各个幂相加来表示 0.3?你不能。你能想到的最好值大约是 0.30000000000000004 (我必须看到确切的二进制数字才能知道它是如何达到这个值的)。