#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;
}
编写此程序可以以特定方式将浮点数四舍五入到小数点后3位;例如65.43296
应该打印为65.43200
,而不是65.432
。
根据逻辑它应该可以工作,但是我得到了一个意外的答案,如下所示:
1234.56789
1234568.00000
1234.567993
解释这种行为。
答案 0 :(得分:1)
尽管输入为"1234.56789"
,但这只是在float a
中保存的值 附近。
float
作为32位对象,只能精确存储 大约2 32 个不同的值。由于float
中的typical binary encoding,1234.56789不是这2 32 之一。而是使用最近的浮点数。
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
,并且由于它也不是2 32 之一,因此结果是最接近的float
1234.5679931640625 // nearest float.
1234.568 // math result of 1234568.0/1000
1234.568115234375 // next nearest float
然后,OP会看到 printf("%.5f\n", 1234.5679931640625)
。
1234.56799
通常,float
将在前导有效位数为6或更少时提供预期的答案。 OP对"1234.56800"
的期望是9位数字。
使用了double
的硬代码,当前导有效数字的数量超过15时,可能会发生类似的意外答案。
答案 1 :(得分:0)
对于您的问题的不一致的解释是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;
}