这是一个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.如果第一次回答的答案是真的,那么我们如何绕过这种四舍五入来获得更准确的结果呢?
答案 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个位置,当您复制时不要错过任何数字; - )