急急急~c语言小问题,是BUG吗?高手请

来源:百度知道 编辑:UC知道 时间:2024/05/18 01:10:12
运行环境Win-TC2.0:
问题1:
main()
{ float s1=153.9,s2=153.909064;
printf("%f %f",s1,s2); /* %.1f %.5f */
getch();
}
为什么输出153.899994 153.909058而不是153.900000 153.909064

问题2:
double dou()
{return 153.909064;}
main()
{ float s; /* double s; */
s=123.456; /* 或者改成 */
printf("%f ",s=dou()); /* s=153.909064 */
printf("%f ",s);
getch();
}
为什么输出153.909064 153.909058而不是153.909064 153.909064

问题3:
double dou()
{return 153.909064;}
main()
{ float s;
s=dou(); /* dou()换成153.909064 */
printf("%f ",dou()); /* printf("%f ",s=dou()); */
printf("%f ",s);
getch();
}
为什么输出153.909064 153.909058而不是153.909064 153.909064

这几个问题搞了我一早上了,求求各位路过的朋友帮忙调试一下。
初学,劳烦大家尽量解答详细些,小弟在此说声谢谢。

1.这涉及到浮点数的格式问题,浮点数在内存中实际上是表示成a乘以2的b次方的形式,a,b都是二进制数,如果是float的话,a有23位,b有8位,所以a只能精确到2的-23次方这个精度.很不幸,153.9表示成二进制数的话,其小数部分是无限的,而计算机连整数和小数部分总共只能保存23位,而这23位重新换成10进制数的话就是153.899994.

3.因为double的精度高,所以153.909064能精确保存,所以printf("%f ",dou()); 的话可以显示正确,而把它的值赋给精度低的float型变量s的话,则数据有丢失.

2.不太清楚,可能是你的编译器有做优化,在编译代码时发现s=dou()会造成数据丢失,所以帮你输出了赋值前的值.

楼主。单浮点型,也就是float的有效数只有7个。也就是只有7个是精确的。其他的都是无效值。因此会不精确。这个是正常的。
还有如果你没有要求他小数位几位的话,他会默认为6位
还有就是如果你用double的话。你的输出最好用%lf。要不他会相当于自动 转成单浮点数。也就是有效只有7位。

建议用double。那么就不会出错了

你的问题1-3都是这样情况

float数据类型是很容易失真的。没有什么。呵。以后多用double类型尽量不用float。那个关于你的第二个问题为什么换成double还是失真?
那是因为你输出的时候又用了f%还是做为float类型输出了。当然还是失真!