如果任一参数为 NaN,什么会导致 C/C++ <、<= 和 == 运算符返回 true?
What would cause the C/C++ <, <=, and == operators to return true if either argument is NaN?
我对IEEE-754浮点比较规则的理解是,如果参数之一或两个都是NaN,除了!=
之外的所有比较运算符将返回false,而!=
运算符将返回true。我可以很容易地用一个简单的独立测试重现这个行为:
for (int ii = 0; ii < 4; ++ii)
{
float a = (ii & 1) != 0 ? NAN : 1.0f;
float b = (ii & 2) != 0 ? NAN : 2.0f;
#define TEST(OP) printf("%4.1f %2s %4.1f => %sn", a, #OP, b, a OP b ? "true" : "false");
TEST(<)
TEST(>)
TEST(<=)
TEST(>=)
TEST(==)
TEST(!=)
}
打印预期的结果:(NaN在MSVC运行时被格式化为-1.$
)
1.0 < 2.0 => true
1.0 > 2.0 => false
1.0 <= 2.0 => true
1.0 >= 2.0 => false
1.0 == 2.0 => false
1.0 != 2.0 => true
-1.$ < 2.0 => false
-1.$ > 2.0 => false
-1.$ <= 2.0 => false
-1.$ >= 2.0 => false
-1.$ == 2.0 => false
-1.$ != 2.0 => true
1.0 < -1.$ => false
1.0 > -1.$ => false
1.0 <= -1.$ => false
1.0 >= -1.$ => false
1.0 == -1.$ => false
1.0 != -1.$ => true
-1.$ < -1.$ => false
-1.$ > -1.$ => false
-1.$ <= -1.$ => false
-1.$ >= -1.$ => false
-1.$ == -1.$ => false
-1.$ != -1.$ => true
然而,当我将这段代码粘贴到应用程序的内循环深处(所有浮点计算都在这里执行)时,我得到了这些令人费解的结果:
1.0 < 2.0 => true
1.0 > 2.0 => false
1.0 <= 2.0 => true
1.0 >= 2.0 => false
1.0 == 2.0 => false
1.0 != 2.0 => true
-1.$ < 2.0 => true
-1.$ > 2.0 => false
-1.$ <= 2.0 => true
-1.$ >= 2.0 => false
-1.$ == 2.0 => true
-1.$ != 2.0 => false
1.0 < -1.$ => true
1.0 > -1.$ => false
1.0 <= -1.$ => true
1.0 >= -1.$ => false
1.0 == -1.$ => true
1.0 != -1.$ => false
-1.$ < -1.$ => true
-1.$ > -1.$ => false
-1.$ <= -1.$ => true
-1.$ >= -1.$ => false
-1.$ == -1.$ => true
-1.$ != -1.$ => false
由于某种原因,<
、<=
和==
操作符在其中一个或两个参数都是NaN时意外返回true。此外,!=
操作符意外返回false。
这是64位代码,使用Visual Studio 2010构建,运行在Intel Xeon E5-2650上。使用_mm_getcsr()
,我已经确认CSR寄存器在两种情况下保持相同的值。
还有什么可以影响像这样的浮点数学行为?
此行为是由于/fp:fast
MSVC编译器选项,它(除其他外)允许编译器执行比较,而不考虑适当的NaN行为,以生成更快的代码。使用/fp:precise
或/fp:strict
会使这些比较在使用NaN参数时按照预期的方式进行。
相关文章:
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 无论条件是否为true,if总是在c++中执行
- 如何防止clang格式在流运算符调用之间添加换行符<<
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- <<操作员在下面的行中工作
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- Arduino-C++ bool 不会从 false 变为 true
- 如何使布尔变量仅在设置为 true 时才为真?
- C++ 如果在 if 为 true 之后运行,为什么还会这样做
- 为什么组合的上限和下限比较的计算结果总是为 true?
- 对于完成布尔值设置为 true 后未停止的循环
- 为什么'typeid(x) == typeid(y)'的计算结果为 true,其中 'x' 和 'y' 分别是 T 和 T& 类型的 id-表达式?
- OLE DB 大容量复制操作始终将 true 加载到位列中
- cin.fail() not returning true
- Fmod 函数清楚地输出一个预期的双精度值,但 if(fmod == 预期的双精度值)的计算结果不是 true
- 如何使用boost定义布尔类,可能的值应该是TRUE或FALSE?
- 如何显式调用运算符<<
- 我在OpenCV中有错误的"approxPolyDP(ROI_Vertices, ROI_Poly, 1.0, true)"
- 如果语句表达式调用函数,则需要测试是否为 true