C的pow()中的参数精度

时间:2012-08-12 14:42:39

标签: c precision math.h

这是一个C代码;

#include<stdio.h>
#include<math.h>
int main()
{
    double n=10.0;
    double automatic = pow(10.0,log10(n)-log10(5.0));
    printf("%.9lf\n",log10(n)-log10(5.0));
    printf("%.9lf\n",pow(10.0,0.30102996));
    double manual = pow(10.0,0.30102996);
    printf("%.9lf %lf\n",automatic, floor(automatic));
    printf("%.9lf %lf\n",manual,floor(manual));
    return 0;
}

输出是:

0.301029996
1.999999836
2.000000000 1.000000
1.999999836 1.000000

从输出我可以推断出在pow(x,y)中y舍入到6位数,因为它的签名是pow(双x,双y),因此0.301029996变为0.301030,这就是为什么自动值为2.000000000否则它与手册相同。

我的问题:
1.我的感染是否正确?
2.如果第一次回答的答案是真的,那么我们如何绕过这种四舍五入来获得更准确的结果呢?

1 个答案:

答案 0 :(得分:3)

pow不会舍入到6位数。它使用双精度,对于IEEE双精度是52位有效数(大约15位小数)。对于那个精度的最后一位数字,它可能准确也可能不准确,但它通常很接近。

2的基数10日志的确切值接近0.301029995663981195213738894724(来源:Wolfram Alpha)。这是一个无理数,因此无法用任何数字系统(十进制或二进制)精确表示。

您的结果显示log10(n)-log10(5.0)返回的值比0.30102996更接近2的精确数学基数10对数。您获得1.999999836的原因是,当您使用0.30102996替换它时,手动使您的值不太准确。这不是舍入值,顺便说一句 - 计算9s。

您的通话pow(10.0,log10(n)-log10(5.0))返回的结果略低于2(由floor显示),但足够接近,在9个位置转为2。使用double类型,你不会比这更好。

所以我真的不知道你的意思是“避免四舍五入”。如果您不想使值不准确,请不要手动将其舍入到9个位置,当您复制时不要错过任何数字; - )