这句话是否正确? :
由于计算机上浮点数的对数分布,大数字的计算不太准确。
这意味着使用1左右的值计算更准确(因为舍入误差),然后是相同的计算,其中每个数字已经用1e20缩放?
答案 0 :(得分:1)
是的,声明是正确的,较大的浮点数不如较小的浮点数。
浮点数具有分配给mantissa的固定位数。如果正在表示的数字需要的位数多于尾数中的位数,则它将被舍入。因此可以更精确地表示较小的数字。
为了使这个更具体,我编写了以下程序,它将逐渐增大的值添加到一个大浮点数和一个小浮点数。为了显示差异,我还包括一个没有舍入的双精度浮点数。但如果尾数更大,那么双倍会遇到同样的问题。
#include <stdio.h>
int main() {
float large_float, small_float, epsilon;
double large_double, small_double;
large_float = 1 << 20;
small_float = 1;
epsilon = 0.1;
large_double = large_float;
small_double = small_float;
printf("large_float\t large_double\t small_float\t small_double\t epsilon\n");
for(int i = 0; i < 10; i++) {
printf("%f\t %f\t %f\t %f\t %f\n", large_float, large_double,small_float, small_double, epsilon);
large_float += epsilon;
large_double += epsilon;
small_float += epsilon;
small_double += epsilon;
epsilon /= 2;
}
return 0;
}
运行此程序会产生以下输出:
large_float large_double small_float small_double epsilon
1048576.000000 1048576.000000 1.000000 1.000000 0.100000
1048576.125000 1048576.100000 1.100000 1.100000 0.050000
1048576.125000 1048576.150000 1.150000 1.150000 0.025000
1048576.125000 1048576.175000 1.175000 1.175000 0.012500
1048576.125000 1048576.187500 1.187500 1.187500 0.006250
1048576.125000 1048576.193750 1.193750 1.193750 0.003125
1048576.125000 1048576.196875 1.196875 1.196875 0.001563
1048576.125000 1048576.198438 1.198437 1.198438 0.000781
1048576.125000 1048576.199219 1.199219 1.199219 0.000391
1048576.125000 1048576.199609 1.199609 1.199609 0.000195
正如您所看到的,large_float
值不如small_float
精确,这可能导致最终结果不准确。