真的很奇怪:
double *data; // uncorrelated
double a,b,c;
double sigma = 1e-309; // denormalized number
try { data = new double[10]; } // uncorrelated
catch(...) { cout << "error"; return 1; }
a = 1/sigma; // infinite
b = exp(-1/sigma); // 0
c = a * b; // NaN
cout << c << endl;
c = (1/sigma) * exp(-1/sigma); // 0
cout << c << endl;
好的,由于某些优化,第二个c结果可能为0。
但:当我删除try / catch块时,第二个c仍然是NaN!为什么这种不同的行为???我的编译器是VC++ 2010 Express。操作系统Windows 7 64位。我只使用iostream和cmath之类的标准库。
编辑:我的第一个观察结果是使用一个空控制台应用程序的Debug + Win32默认设置。使用Release + Win32,结果为:第一个c 0,第二个c NaN-无论是否存在try / catch!概要:
//Debug+Win32 // Release+Win32
//with try //without //with try //without
c = a * b; // NaN NaN 0 0
c = (1/sigma) * exp(-1/sigma); // 0 NaN NaN NaN
编辑2 :当我在C++ / codegeneration中设置
/fp:strict
开关时,结果与Debug + Win32相同,但是对于Release + Win32,无论是否尝试,它都将更改为c = a * b; // NaN
和c = (1/sigma) * exp(-1/sigma); // 0
。我不明白为什么它会在Debug + Win32且没有任何先前尝试的情况下仍保持NaN+NaN
的状态。当结果与发布不同(取决于先前的尝试)而与/fp:strict
不同时,如何调试必须浮点安全的程序?编辑3 :这是一个完整程序:
// On VC++ 2010 Express in default Win32-Debug mode for empty console application.
// OS: Windows 7 Pro 64-Bit, CPU: Intel Core i5.
// Even when /fp:strict is set, same behaviour.
//
// Win32-Release mode: first c == 0, second c == NaN (independent of try)
// with /fp:strict: first c == NaN, second c == 0 (also independent of try)
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double *data; // uncorrelated
double a,b,c;
double sigma = 1e-309; // denormalized number
try { data = new double[10]; } // uncorrelated
catch(...) { cout << "error"; return 1; }
a = 1/sigma; // infinite
b = exp(-1/sigma); // 0
c = a * b; // NaN
cout << c << endl;
c = (1/sigma) * exp(-1/sigma); // 0 with preceding try or
cout << c << endl; // NaN without preceding try
cin.get();
return 0;
}
最佳答案
由于寄存器分配/使用的差异,可能会发生这些事情。例如,使用try-catch块,可以将sigma
的值另存为64位double
,然后从内存中重新加载,而没有该块,它可以使用更高精度的80位寄存器(请参见http://en.wikipedia.org/wiki/Extended_precision)而不进行舍入到64位。我建议您在需要时检查一下程序集。
关于c++ - 浮点NaN取决于C++中不相关的异常处理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20068186/