Java:使用双精度不准确

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

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

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

I'm making a histogram class, and I'm encountering a weird issue.

这是该类的基础知识,还有更多方法,但与问题无关.

Here are the basics of the class, there are more methods but they aren't relevant to the issue.

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 + "		");
}

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

the problem happens when I plot the frequencies. I've created 2 instances. new Histogram(0, 1, 10); new Histogram(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    

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

So my question is, why am I getting the really long decimal limits in the first example, but not the second one?

推荐答案

有些小数不能用双精度值精确表示.0.3 是这些值之一.

Some decimals cannot be exactly represented by double values. 0.3 is one of those values.

所有小于某个数字(我忘记了)的整数值恰好有一个双精度值的精确表示,所以你看不到近似值.

All integer values less than a certain number (I forget which) happen to have an exact representation by a double value, so you don't see the approximation.

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

Consider how we think of numbers: the number 123 is represented as (1 * 100) + (2 * 10) + (3 * 1). We use 10 as our base. Binary numbers use two. So when you look at fractions of a number, how could you represent 0.3 by adding individual powers of 2? You can't. The best you can come up with is about 0.30000000000000004 (I'd have to see the exact binary digits to see how it reaches that).

相关文章