C 程序给出了意想不到的答案
C program is giving unexpected answer
#include <stdio.h>
int main(){
float a;
scanf("%f",&a);
a=(int)(a*1000+0.5);
printf("%.5f\n",a);
a=a/1000;
printf("%.5f\n",a);
return 0;
}
编写此程序是为了以特定方式将浮点数四舍五入到小数点后三位;例如65.43296
应打印为 65.43200
,而不是 65.432
。
根据逻辑,它应该可以工作,但我得到了一个意想不到的答案,如下所示:
1234.56789
1234568.00000
1234.567993
解释这种行为。
问题中不一致的解释是 float
类型适用的小数位数。它有一个简单的精度范围 3.4 E-38 to 3.4E+38
(有 4 个字节)。如果您应该使用 double
的范围为 1.7 E-308 to 1.7E+308
,但会占用更多内存(8 字节)。
#include <stdio.h>
int main(){
double a;
scanf("%lf",&a);
a=(int)(a*1000+0.5);
printf("%.5f\n",a);
a=a/1000;
printf("%.5lf\n",a);
return 0;
}
虽然输入是 "1234.56789"
,但仅 接近 float a
中保存的值。
float
作为32位对象,只能存储正好约232个不同的值。由于 float
的 typical binary encoding,1234.56789 不是那些 232 之一。而是使用最近的浮点数。
1234.56787109375 // nearest float's exact value
1234.56789
1234.5679931640625 // next nearest float's exact value
a*1000+0.5
预计会产生 1234568.375,(int)(a*1000+0.5)
会产生 1234568.0。到目前为止没有太大的惊喜。
商 a/1000;
也是一个 float
,因为它也不是 232 之一,结果是最接近的 float
1234.5679931640625 // nearest float.
1234.568 // math result of 1234568.0/1000
1234.568115234375 // next nearest float
printf("%.5f\n", 1234.5679931640625)
如 OP 所见。
1234.56799
一般来说,float
会在前导有效数字位数为 6 或更少时提供预期的答案。 OP 对 "1234.56800"
的期望是 9 位数。
如果使用代码 double
,当前导有效数字超过 15 位时,可能会出现类似的意外答案。
#include <stdio.h>
int main(){
float a;
scanf("%f",&a);
a=(int)(a*1000+0.5);
printf("%.5f\n",a);
a=a/1000;
printf("%.5f\n",a);
return 0;
}
编写此程序是为了以特定方式将浮点数四舍五入到小数点后三位;例如65.43296
应打印为 65.43200
,而不是 65.432
。
根据逻辑,它应该可以工作,但我得到了一个意想不到的答案,如下所示:
1234.56789
1234568.00000
1234.567993
解释这种行为。
问题中不一致的解释是 float
类型适用的小数位数。它有一个简单的精度范围 3.4 E-38 to 3.4E+38
(有 4 个字节)。如果您应该使用 double
的范围为 1.7 E-308 to 1.7E+308
,但会占用更多内存(8 字节)。
#include <stdio.h>
int main(){
double a;
scanf("%lf",&a);
a=(int)(a*1000+0.5);
printf("%.5f\n",a);
a=a/1000;
printf("%.5lf\n",a);
return 0;
}
虽然输入是 "1234.56789"
,但仅 接近 float a
中保存的值。
float
作为32位对象,只能存储正好约232个不同的值。由于 float
的 typical binary encoding,1234.56789 不是那些 232 之一。而是使用最近的浮点数。
1234.56787109375 // nearest float's exact value
1234.56789
1234.5679931640625 // next nearest float's exact value
a*1000+0.5
预计会产生 1234568.375,(int)(a*1000+0.5)
会产生 1234568.0。到目前为止没有太大的惊喜。
商 a/1000;
也是一个 float
,因为它也不是 232 之一,结果是最接近的 float
1234.5679931640625 // nearest float.
1234.568 // math result of 1234568.0/1000
1234.568115234375 // next nearest float
printf("%.5f\n", 1234.5679931640625)
如 OP 所见。
1234.56799
一般来说,float
会在前导有效数字位数为 6 或更少时提供预期的答案。 OP 对 "1234.56800"
的期望是 9 位数。
如果使用代码 double
,当前导有效数字超过 15 位时,可能会出现类似的意外答案。