Sea*_*ean 44 c c++ nan ieee-754
我对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(!=)
}
Run Code Online (Sandbox Code Playgroud)
这将打印预期结果:(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
Run Code Online (Sandbox Code Playgroud)
但是,当我将这段代码粘贴到应用程序内部循环的深处时,执行所有浮点计算时,我得到了这些无法解释的结果:
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
Run Code Online (Sandbox Code Playgroud)
出于某种原因,<,<=,和==运营商意外地返回true时,一个或两个参数都为NaN.此外,!=操作员意外地返回错误.
这是使用Visual Studio 2010构建的64位代码,运行在Intel Xeon E5-2650上.使用_mm_getcsr(),我已确认CSR寄存器在两种情况下都保持相同的值.
还有什么可以影响像这样的浮点数学的行为?
Sea*_*ean 54
此行为是由于/fp:fastMSVC编译器选项(其中包括)允许编译器执行比较而不考虑正确的NaN行为以生成更快的代码.使用/fp:precise或/fp:strict替代使这些比较在呈现NaN参数时表现得如预期.
| 归档时间: |
|
| 查看次数: |
2046 次 |
| 最近记录: |