Java:使用 double 不准确
制作直方图类,我遇到了一个奇怪的问题。
这是该类的基础知识,还有更多方法,但它们与问题无关。
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");
}
当我绘制频率时就会出现问题。我已经创建了 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
所以我的问题是,为什么我在第一个示例中得到非常长的小数限制,但在第二个示例中却没有?
Possible Duplicate:
Retain precision with Doubles in java
Strange floating-point behaviour in a Java program
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 + "\t\t");
}
the problem happens when I plot the frequencies. I've created 2 instances.
new Histogram(0, 1, 10);
new Histogram(0, 10, 10);
This is what they output.
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
双打并不准确。
这是因为存在无限可能的实数,而表示这些数字的位数却是有限的。
看一下:每个程序员都应该了解浮点知识算术
doubles are not exact.
It is because there are infinite possible real numbers and only finite number of bits to represent these numbers.
have a look at: what every programmer should know about floating point arithmetic
来自浮点指南:
这就是你的第一个例子。第二个只涉及整数,不涉及分数,整数可以用二进制浮点格式精确表示(最多 52 位)。
From The Floating-Point Guide:
That accounts for your first example. The second one only involves integers, not fractions, and integers can be represented exactly in the binary floating-point format (up to 52 bits).
有些小数不能用 double 值精确表示。 0.3 是这些值之一。
所有小于某个数字(我忘记了哪个数字)的整数值碰巧都有一个双精度值的精确表示,因此您看不到近似值。
考虑一下我们如何看待数字:数字 123 表示为 (1 * 100) + (2 * 10) + (3 * 1)。我们使用 10 作为基数。二进制数使用两个。那么,当您查看一个数字的分数时,如何通过将 2 的各个幂相加来表示 0.3?你不能。你能想到的最好值大约是 0.30000000000000004 (我必须查看确切的二进制数字才能知道它是如何达到这个值的)。
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.
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).
他们在第二种情况下四舍五入。另请参阅Ruby - 乘法问题 - 这是同样的问题。
They're getting rounded in the second case. See also Ruby - Multiplication issue — it's the same problem.