为什么这个返回nan?

Why is this returning nan?

代码:

double v = (180*9.8)/(42*42);  // v should be 1.000000
printf("%f ",v);
cout<<asin(v);

输出:

1.000000
nan

我使用的是 64 位 mingw (win 7)。

这是因为 v 大于 1(当 (180*9.8)/(42*42) 使用双精度浮点计算时)。

double v = (180*9.8)/(42*42); 

std::cout.precision(20);

cout << fixed << v << endl;

输出:

1.00000000000000022204
nan

DEMO

要摆脱有限精度的问题,可以执行以下操作。

if (v > 1)
    v = 1;
if (v < -1)
    v = -1;

9.8 是一个无法用浮点数精确表示的值。也就是说,实际存储的值等于9.8 + delta,其中delta是一个小值,可以是正数也可以是负数。

如果delta对于你的浮点表示法(大概是IEEE)是正的,那么180*9.8会大于1764,所以v的值会超过1asin() 的唯一有效输入在 -11 范围内。虽然 asin() 中的 return 值未指定为超出该范围的值,但 NaN 是报告该范围的一种方式。