来自pow的异常输出

时间:2013-06-04 16:44:30

标签: c pow

以下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编译器。 它没有任何意义,对吧? 有任何想法吗? (那个战俘(10,2)可能是某种东西 像99.9999不解释第一个 输出。而且,我也一样 输出即使我包括math.h)

3 个答案:

答案 0 :(得分:6)

您使用的是质量差的数学库。一个好的数学库可以为完全可表示的值返回精确的结果。

通常,数学库例程必须是近似值,因为浮点格式不能精确地表示精确的数学结果,并且因为计算各种函数很困难。但是,对于pow,可以准确表示的结果数量有限,例如10 2 。一个好的数学库将确保正确返回这些结果。您正在使用的库无法做到这一点。

答案 1 :(得分:3)

将结果计算存储为double s。使用double代替%f打印为%d。你会发现99更像是99.999997,这应该更有意义。

通常,在使用任何浮点数学时,您应该假设结果是近似的;也就是说,两个方向都有点偏差。所以当你想要确切的结果时 - 就像你在这里做的那样 - 你将遇到麻烦。

在使用函数之前,您应该始终了解函数的返回类型。见,例如, cplusplus.com

double pow (double base, double exponent); /* C90 */

从其他答案我了解到,有些情况下,您可以期望pow或其他浮点数学是精确的。了解the necessary imprecision that plagues floating point math后,请参阅这些内容。

答案 2 :(得分:2)

您的变量t1t2t3必须是double类型,因为pow()会返回双倍。


但如果您确实希望它们属于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,因为它的类型为intt3也是如此。

输出将是:

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. ... */