真的很奇怪:
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:当我/fp:strict
在 C++/代码生成中设置开关时,结果与 Debug+Win32 相同,但使用 Release+Win32 时,c = a * b; // NaN
无论c = (1/sigma) * exp(-1/sigma); // 0
是否尝试,它都会更改为。我不明白为什么它保留NaN+NaN
在 Debug+Win32 并且没有之前的尝试。当结果与 Release 不同时,如何调试必须是浮点安全的程序/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;
}