为什么这个返回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
要摆脱有限精度的问题,可以执行以下操作。
if (v > 1)
v = 1;
if (v < -1)
v = -1;
9.8
是一个无法用浮点数精确表示的值。也就是说,实际存储的值等于9.8 + delta
,其中delta
是一个小值,可以是正数也可以是负数。
如果delta
对于你的浮点表示法(大概是IEEE)是正的,那么180*9.8
会大于1764
,所以v
的值会超过1
。 asin()
的唯一有效输入在 -1
到 1
范围内。虽然 asin()
中的 return 值未指定为超出该范围的值,但 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
要摆脱有限精度的问题,可以执行以下操作。
if (v > 1)
v = 1;
if (v < -1)
v = -1;
9.8
是一个无法用浮点数精确表示的值。也就是说,实际存储的值等于9.8 + delta
,其中delta
是一个小值,可以是正数也可以是负数。
如果delta
对于你的浮点表示法(大概是IEEE)是正的,那么180*9.8
会大于1764
,所以v
的值会超过1
。 asin()
的唯一有效输入在 -1
到 1
范围内。虽然 asin()
中的 return 值未指定为超出该范围的值,但 NaN 是报告该范围的一种方式。