来自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或其他浮点数学是精确的。 一旦你理解了困扰浮点数学的必要的不精确性 ,请参考这些。

您的变量t1t2t3必须是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.0200.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. ... */