来自pow的exception输出
以下C代码
int main(){ int n=10; int t1=pow(10,2); int t2=pow(n,2); int t3=2*pow(n,2); printf("%d\n",t1); printf("%d\n",t2); printf("%d\n",t3); return (0); }
给出以下输出
100 99 199
我正在使用devcpp编译器。 它没有任何意义,对吧? 有任何想法吗? (那个pow(10,2)可能就像99.9999那样不能解释第一个输出。而且,即使我包含math.h,我也得到了相同的输出。)
您使用的是质量差的数学库。 一个好的数学库可以为完全可表示的值返回精确的结果。
通常,数学库例程必须是近似值,因为浮点格式不能精确地表示精确的数学结果,并且因为计算各种函数很困难。 但是,对于pow
,可以准确表示的结果数量有限,例如10 2 。 一个好的数学库将确保正确返回这些结果。 您正在使用的库无法执行此操作。
将结果计算存储为double
。 使用%f
而不是%d
打印为double
。 你会看到99
真的更像99.999997
,这应该更有意义。
通常,在使用任何浮点数学时,您应该假设结果是近似的; 也就是说,两个方向都有点偏差。 所以当你想要精确的结果时 – 就像你在这里做的那样 – 你会遇到麻烦。
在使用它们之前,您应该始终了解函数的返回类型。 参见,例如cplusplus.com :
double pow (double base, double exponent); /* C90 */
从其他答案我了解到有些情况下,你可以期望pow
或其他浮点数学是精确的。 一旦你理解了困扰浮点数学的必要的不精确性 ,请参考这些。
您的变量t1
, t2
和t3
必须是double
类型,因为pow()
返回double。
但是如果你确实希望它们是int
类型 ,请使用round()
函数。
int t1 = pow(10,2); int t2 = round(pow(n,2)); int t3 = 2 * round(pow(n,2));
它将返回值99.9...
和199.9...
到100.0
和200.0
。 然后t2 == 100
因为它是int
类型, t3
。
输出将是:
100 100 200
因为round
函数返回最接近x舍入中间情况的整数值,而不管当前的舍入方向如何。
更新:这是math.h
评论:
/* Excess precision when using a 64-bit mantissa for FPU math ops can cause unexpected results with some of the MSVCRT math functions. For example, unless the function return value is stored (truncating to 53-bit mantissa), calls to pow with both x and y as integral values sometimes produce a non-integral result. ... */