如果任一参数为 NaN,什么会导致 C/C++ <、<= 和 == 运算符返回 true?

2024-04-08

我对 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 => %s\n", a, #OP, b, a OP b ? "true" : "false");
    TEST(<)
    TEST(>)
    TEST(<=)
    TEST(>=)
    TEST(==)
    TEST(!=)
}

这将打印预期结果:(NaN 的格式为-1.$在 MSVC 运行时)

 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

由于某种原因,<, <=, and ==当一个或两个参数为 NaN 时,运算符意外返回 true。此外,!=运算符意外返回 false。

这是 64 位代码,使用 Visual Studio 2010 构建,在 Intel Xeon E5-2650 上运行。使用_mm_getcsr(),我已经确认 CSR 寄存器在两种情况下都具有相同的值。

还有什么可以影响这样的浮点数学行为?


这种行为是由于/fp:fast http://msdn.microsoft.com/en-us/library/e7s85ffb.aspxMSVC 编译器选项,它(除其他外)允许编译器执行比较,而不考虑正确的 NaN 行为,以生成更快的代码。使用/fp:precise http://msdn.microsoft.com/en-us/library/e7s85ffb.aspx or /fp:strict http://msdn.microsoft.com/en-us/library/e7s85ffb.aspx相反,当提供 NaN 参数时,这些比较会按预期运行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果任一参数为 NaN,什么会导致 C/C++ <、<= 和 == 运算符返回 true? 的相关文章

随机推荐