C语言中的浮点数混淆问题

3

我的代码是

void main()
{
    float a = 0.7;
    if (a < 0.7)
        printf("c");
    else
        printf("c++");
} 

它打印出 C,这是正确的,因为a被视为双精度常量值,其值为0.699999,小于0.7

现在,如果我将a中的值更改为0.1,0.2,0.3直到0.9,并且在if条件中也进行更改,则除了0.7和0.9之外,它打印出C ++,即两者相等或a大于0.9

为什么不考虑所有值?


12
阅读《每个程序员都应该知道的浮点数算术》(http://floating-point-gui.de/)。我会为您进行翻译,并尽可能使其易于理解,同时保持原意不变。 - pmg
它是否对另一种情况同样认真地处理<=?(看起来是这样的)。 - Captain Giraffe
@CaptainGiraffe 我还没有检查过,让我也来看看。 - John
所以,@nos为什么会显示C++输出0.8? - John
@StephenCanon 我搜索了但没有找到,谢谢您的帮助 :) - John
显示剩余2条评论
1个回答

11
你在谈论哪个“概念”?
你提到的所有数字都无法在二进制浮点格式中精确表示(不管精度如何)。你提到的所有数字在小数点后面都有无穷多个二进制数字。
由于floatdouble都没有无限的精度,因此在floatdouble格式中,实现将以最接近的可表示的二进制浮点值来近似这些值。这些近似值在floatdouble中是不同的。并且float的近似值可能会比double的近似值更大或更小。因此出现了你观察到的结果。
例如,在我的实现中,0.7的值被表示为
+6.9999998807907104e-0001 - float
+6.9999999999999995e-0001 - double

与此同时,0.1 的值表示为

+1.0000000149011611e-0001 - float
+1.0000000000000000e-0001 - double

正如您所看到的,在第一个示例中,double表示比float表示更大,而在第二个示例中则相反。(上述是十进制表示法,它们自己就被四舍五入了,但它们具有足够的精度来很好地说明这种效果。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接