Visual c++ x64 VS2019-VS2015中的非一致性比较

Visual c++ x64 VS2019-VS2015中的非一致性比较,visual-c++,visual-studio-2019,Visual C++,Visual Studio 2019,我有一个简单的程序: #include <iostream> #include <cmath> int main() { double dNan = std::nan("nan"); double dNotNan = 3961.12345; if (dNan == dNotNan) std::cout << "Nan == Not Nan" << std::endl; else st

我有一个简单的程序:

#include <iostream>
#include <cmath>
int main()
{
    double dNan = std::nan("nan");
    double dNotNan = 3961.12345;

    if (dNan == dNotNan)
        std::cout << "Nan == Not Nan" << std::endl;
    else
        std::cout << "Nan != Not Nan" << std::endl;   
}
对于平台x86或/fp:precise,输出为预期的“Nan!=非Nan”

为比较生成的汇编程序为:

00007FF6F8E7101F  ucomisd     xmm0,mmword ptr [__real@40aef23f34d6a162 (07FF6F8E732B8h)]  
00007FF6F8E71027  je          main+30h (07FF6F8E71030h)  
在哪里__real@40aef23f34d6a162是3961.12345值,xmm0包含NaN“0000000000000000-7FF800000000000”。UCOMISD指令的结果是标志ZP、CF、PF全部设置,这表示“无序”,即至少有一个操作数为NaN。JE指令仅测试ZF标志,当两个操作数相等时,ZF标志设置为1

文件中说“特殊值(NaN,+无穷大,-无穷大,-0.0)可能不会传播或严格遵守IEEE-754标准”,其他地方给出的例子为NaN-NaN=0,但比较行为似乎远远超出了“不严格遵守标准”


我找不到这方面的任何信息;这真的是预期的行为还是我刚刚被编译器错误绊倒了?

/fp:strict
在计算上比
/fp:precise
更昂贵,因为编译器必须插入额外的指令来捕获异常,并允许程序在运行时访问或修改浮点环境。如果您的代码不使用此功能,但需要源代码排序和舍入,或依赖于特殊值,请使用
/fp:precise
。有关更多详细信息,我建议您可以参考链接:“
/fp:fast
适用于不依赖于处理特殊值(如NaN)的标准规则的程序。”你似乎很在意——所以不要使用
/fp:fast
@Igor谢谢;是的,看起来这就是必须发生的事情。问题是,从快速到精确的转换不仅会降低计算速度(这可能是正常的),而且还会以不可预测的方式改变计算结果(这可能不是)。@Jeaninez是的,这里出现的问题是x86和x64编译器之间的行为差异。这意味着客户可以同时运行当前的32位软件和新的64位版本,并查看输出中的差异。
00007FF6F8E7101F  ucomisd     xmm0,mmword ptr [__real@40aef23f34d6a162 (07FF6F8E732B8h)]  
00007FF6F8E71027  je          main+30h (07FF6F8E71030h)