c ++ 两个双精度值的比较无法正常工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18971533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
c++ comparison of two double values not working properly
提问by tuks
Look at this code:
看看这段代码:
#include <cmath>
#include <iostream>
using namespace std;
class Sphere
{
double r;
public:
double V() const { return (4/3) * 3.14 * pow(r,3); }
bool equal(const Sphere& s) const
{
cout << V() << " == " << s.V() << " : " << ( V() == s.V() );
return ( V() == s.V() );
}
explicit Sphere(double rr = 1): r(rr){}
};
main()
{
Sphere s(3);
s.equal(s);
}
The output is 84.78 == 84.78 : 0
which means the same method doesn't return the same value every time, even though all parameters are static?
输出是84.78 == 84.78 : 0
这意味着相同的方法不会每次都返回相同的值,即使所有参数都是静态的?
But if I write 3.0
instead of 3.14
in the V()
method definition, like this:
但是如果我写3.0
而不是3.14
在V()
方法定义中,像这样:
double V() const { return (4/3) * 3.0 * pow(r,3); }
Then, the output is: 84.78 == 84.78 : 1
然后,输出是: 84.78 == 84.78 : 1
What is going on here? I need this method, for my program, which will compare volumes of two objects, but it is impossible? I banged my head for so long to figure out what is the cause of the problem and luckily I found it, but now I don't understand why?? Does it have something to do with the compiler (GCC) or am I missing something important here?
这里发生了什么?我需要这种方法,用于我的程序,它将比较两个对象的体积,但这是不可能的吗?我撞了这么久想弄清楚问题的原因是什么,幸运的是我找到了它,但现在我不明白为什么?它与编译器(GCC)有关还是我在这里遗漏了一些重要的东西?
回答by nijansen
Comparing floating point values using the ==
operator is very error prone; two values that shouldbe equal may not be due to arithmetic rounding errors. The common way to compare these is to use an epsilon:
使用==
运算符比较浮点值很容易出错;应该相等的两个值可能不是由于算术舍入错误。比较这些的常用方法是使用 epsilon:
bool double_equals(double a, double b, double epsilon = 0.001)
{
return std::abs(a - b) < epsilon;
}
回答by gnasher729
There are two problems with floating point comparisons:
浮点比较有两个问题:
(1) Floating point operations usually involve at least tiny rounding errors which are hard to predict. Therefore two floating point operations that should mathematically give the same result (like 4.7 * (1.0 / 3.14) vs. 4.7 / 3.14) may give different results.
(1) 浮点运算通常至少涉及难以预测的微小舍入误差。因此,应该在数学上给出相同结果的两个浮点运算(如 4.7 * (1.0 / 3.14) 与 4.7 / 3.14)可能会给出不同的结果。
(2) The compiler is allowed to do floating point operations sometimes with higher precision than necessary. It is also allowed to do the exact same floating point operations with just the precision that was necessary at other times. Therefore the exact same operation may produce slightly different results, which is what you see here.
(2) 有时允许编译器以比需要更高的精度进行浮点运算。还允许以其他时间所需的精度执行完全相同的浮点运算。因此,完全相同的操作可能会产生略有不同的结果,这就是您在此处看到的。
To solve the OP's problem, this looks like it is caused by (2). I'd try to find if there are any compiler options that can prevent the compiler from using higher precision than needed.
为了解决OP的问题,这看起来是由(2)引起的。我会尝试查找是否有任何编译器选项可以阻止编译器使用比需要更高的精度。