#include <stdio.h>
#include <conio.h>
main()
{
float a = 0.7;
if(a < 0.7)
printf("C");
else
printf("C++");
}
在上面的代码中,输出为C
。我在Code :: Blocks和Pelles C中尝试了这个代码,但得到了相同的答案。我想详细了解这个的原因!
答案 0 :(得分:20)
在二进制中,0.7是:
b0.1011001100110011001100110011001100110011001100110011001100110...
但是,0.7
是一个双精度文字,其值为0.7四舍五入到最接近的可表示的双精度值,即:
b0.10110011001100110011001100110011001100110011001100110
十进制,这正是:
0.6999999999999999555910790149937383830547332763671875
当您编写float a = 0.7
时,该双精度值再次舍入为单精度,a
获取二进制值:
b0.101100110011001100110011
这正是
0.699999988079071044921875
十进制。
当您进行比较(a < 0.7)
时,您将比较此单精度值(转换为double,它不会舍入,因为所有单精度值都可以双精度表示)到原始双精度值。因为
0.699999988079071044921875 < 0.6999999999999999555910790149937383830547332763671875
比较正确返回true,程序将打印"C"
。
请注意,这些在C ++中没有任何不同,相反的代码出现。某些(数字上不安全的)编译器优化可以改变行为,但这些并不是C或C ++独有的。
答案 1 :(得分:8)
这是因为0.7
的类型为double
,因此a
会转换为double
并在此类型中进行比较。由于0.7
在二进制浮点中无法完全表示,因此会出现一些舍入误差,并且比较结果为真。
你可以:
if( a < 0.7f ) {
....
但实际上这种效果对C ++也是如此,所以你的条件并不完全正确。
答案 2 :(得分:3)
并非所有数字都可以在计算机中准确表示,因此只要您使用浮点数(例如浮点数和双精度数),就应该预计每个存储的数字中都会出现一个小的,不可预测的错误。不,它不是随机或不可预测的,但在你了解更多信息之前,你可以认为它是不可预测的。因此,诸如 a <0.7 之类的比较可能证明是真的,而事实并非如此。不要编写依赖于它的代码。