【发布时间】:2018-08-17 22:03:44
【问题描述】:
我编写了这段代码,它只是简单地将 n 个数字的列表相加,以练习浮点运算,但我不明白:
我正在使用浮点数,这意味着我有 7 位精度,因此,如果我执行 10002*10002=100040004 操作,数据类型浮点数的结果将为 100040000.000000,因为我丢失了第 7 位以外的任何数字(程序仍然知道指数,如 here)。
如果这个程序中的输入是
3
10000
10001
10002
但是,您会看到,当这个程序计算 30003*30003=900180009 时,我们有 30003*30003=900180032.000000
我理解这个 32 出现是因为我正在使用 float,我的目标不是让程序更精确,而是理解为什么会发生这种情况。为什么是 900180032.000000 而不是 900180000.000000?为什么即使数字的大小相同,这个十进制噪声(32)也会出现在 30003*30003 而不是 10002*10002 中?感谢您的宝贵时间。
#include <stdio.h>
#include <math.h>
#define MAX_SIZE 200
int main()
{
int numbers[MAX_SIZE];
int i, N;
float sum=0;
float sumb=0;
float sumc=0;
printf("introduce n" );
scanf("%d", &N);
printf("write %d numbers:\n", N);
for(i=0; i<N; i++)
{
scanf("%d", &numbers[i]);
}
int r=0;
while (r<N){
sum=sum+numbers[r];
sumb=sumb+(numbers[r]*numbers[r]);
printf("sum is %f\n",sum);
printf("sumb is %f\n",sumb);
r++;
}
sumc=(sum*sum);
printf("sumc is %f\n",sumc);
}
【问题讨论】:
-
有时,这与使用的表示形式和可用的位一样接近。它是浮点数。它发生了......
-
求和时浮点累加错误。您可以使用
double来降低效果 -
不久前我还建议您联系this answer I wrote。
-
你的数字大小不一样。它们相差 9 倍,这意味着二进制表示需要 3-4 个额外的位。因此,通过四舍五入到可以存储的下一个更高或更低值引入的误差会大 8 或 16 倍。虽然将第一个数字四舍五入会导致 -4 的误差,但第二个数字可能是 +/-64号码。
-
不,100040000.000000 有 15 个有效数字。浮点数在尾数中有 24 位(23 存储 + 1 隐式),因此只能表示 2^24 = 16777216 个不同的值。或 log10(16777216) = 7.2 位有效数字。由于每次转换和计算的舍入,您会损失 0.5 位。因此,当您从十进制转换为二进制并再次转换回十进制以显示该值时,您最多只剩下 23 位精度。 log10(2^23) = 6 位有效数字。残酷的数学,如果在尾数中多一点浮点数,效果会更好。
标签: c floating-point