我发现一些简单的代码导致GCC 4.6.1与Visual Studio(2008& 2012)或OSX上的Clang 7.3.0的意外(和不正确)不等式比较。
这是一个简化的代码段:
typedef float ftype;
struct Foo
{
ftype v;
Foo(): v(16.0f / 60.0f) {}
ftype val() const {return v * 60.0f;}
};
void bar()
{
Foo f;
ftype v = f.val();
if (v != f.val())
printf("inequal");
}
如果ftype的typedef为double,则问题不会发生。这可能与编译器内联有关吗?也许实际上会返回一个double而不是float?
答案 0 :(得分:1)
在您的代码段中,您可以使用简单的“==”或“!=”有效地将两个实数(浮点数或双精度数)相互比较。 不幸的是,由于浮点运算的发生,这种方法对实数不起作用,即与整数相比,实数在存储器中没有精确存储。
你必须比较考虑一些公差的两个实数,这个公差取决于你使用的类型(浮动或双重)和机器。
虽然简单的解决方案(如下所示)可能有效,但您必须将其集成到基于模板的代码中。
#include<limits>
#include<cmath>
TOL=std::numeric_limits<float>::epsilon()
if (std::abs(v - f.val())<TOL)
{
//some code
}
你应该看一下Floating-Point Guide。 StackOverflow上的答案也应该有所帮助:
How to correctly and standardly compare floats?
What is the most effective way for float and double comparison?
UPD:使用差异代替根据@ doug评论修正的abs值的错误。