C++ 中的舍入误差

发布于 2024-11-06 10:54:39 字数 636 浏览 8 评论 0原文

可能的重复:
为什么十进制数不能用二进制精确表示?

语言 c++ 我正在声明一个数组,并在其中保存数字(双精度类型)。然后我开始比较数组中每两个元素之间的差异。 例如

a[1] = 0.05
a[2] = 0.1
a[3] = 0.15

这样 当我执行以下操作时,

if(a[3] - a[2] == a[2] - a[1] )

条件变为错误!

经过调试,我发现数组中保存的是0.05 0.0499......993 0.10 和 0.15 的情况类似,

我该如何克服这个问题?

Possible Duplicate:
Why can't decimal numbers be represented exactly in binary?

Language c++
I'm declaring an array and i save numbers (type double) in it. Then i start comparing the difference between each two elements in the array.
for example

a[1] = 0.05
a[2] = 0.1
a[3] = 0.15

so
when i do the following

if(a[3] - a[2] == a[2] - a[1] )

the condition becomes false!!

After debugging, i found out that 0.05 is saved in the array as
0.0499......993
and the case is similar with 0.10 and 0.15

How can i overcome this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦纸 2024-11-13 10:54:39

您永远不应该比较浮点数是否完全相等。

您应该阅读每个计算机科学家应该了解的浮点知识算术找出原因。

You should never compare floating point numbers for exact equality.

You should read What Every Computer Scientist Should Know About Floating-Point Arithmetic to figure out why.

乱了心跳 2024-11-13 10:54:39

如果您想进行精确计算,您可能需要考虑使用有理数。可以在 C++ 中实现有理数类。 Boost.Rational 就是一个例子。

如果您想使用浮点,您可能需要比较“接近度”,而不是相等性,如下所示:

const float EPSILON = 0.0001; //< Some acceptable limit for equivalence
float d1 = a[3] - a[2];
float d2 = a[2] - a[1];

if (fabs(d1 - d2) < EPSILON) {
    // Consider d1 and d2 eqivalent
}

If you want to do exact calculations, you might want to look into using rational numbers. It is possible to implement a class for rational numbers in C++. Boost.Rational is an example of this.

If you want to use floating point, you probably want to do comparisons for "closeness", rather than equality, like this:

const float EPSILON = 0.0001; //< Some acceptable limit for equivalence
float d1 = a[3] - a[2];
float d2 = a[2] - a[1];

if (fabs(d1 - d2) < EPSILON) {
    // Consider d1 and d2 eqivalent
}
灯下孤影 2024-11-13 10:54:39

浮点数学是计算机不会给出您通常期望的结果的领域之一。请参阅以供参考。

你能做的就是考虑类似的事情
增量 = 0.00001
并检查是否 fabs((a[3]-a[2]) - (a[2]-a[1])) fabs((a[3]-a[2]) - (a[2]-a[1])) < delta

注意:如果这与货币或货币数据有关,那么只需使用整数/长整型等。出于上述原因并在上面的链接中进一步解释,使用浮点/双精度来表示货币是一件坏事。

Floating point mathematics is one area where computers will not give results as you would normally expect. See this for reference.

What you can do is consider something like
delta = 0.00001
and check if fabs((a[3]-a[2]) - (a[2]-a[1])) < delta

Note: If this has anything to do with currency or monetary data then just use integers/long etc. Using float/double to represent money is a bad bad thing, for reasons mentioned above and explained further in the link above.

半边脸i 2024-11-13 10:54:39

您有多种选择:

(1) 使用精确存储这些数字的类型。对于这些数字,最简单的可能是使用 int 并将它们存储为原始数字的 100 倍。

(2) 发现比较双精度数是否相等是一个糟糕的策略。请注意,当您将数字存储为双精度数时,有些数字无法以固定位数的二进制精确表示。 0.05(以及 0.5 5 50 等)就是这些数字之一。

You've got several options:

(1) Use a type that stores these numbers precisely. For these numbers, it's easiest probably to use int and store them as 100x the original number.

(2) figure out that comparing doubles for equality is a bad strategy. See, when you store numbers as doubles, there are numbers that can't be represented exactly in binary in a fixed number of bits. 0.05 (as well as 0.5 5 50 and so on) is one of those numbers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文