为什么可以比较浮点数?

时间:2010-08-31 09:36:25

标签: c++ c floating-point

  

可能重复:
  strange output in comparision of float with float literal

#include<stdio.h>
int main()
{
float me = 1.7;
if(me==1.7)
   printf("C");
else
   printf("C++");
}

Output: C++

现在说这种行为的原因是许多浮点数不能用二进制的绝对精度表示。

我的问题是 - 如果计算机以二进制方式思考和操作。 me表示1.7的任何不确定性在比较时都与(float)1.7相同。所以两者都应该是平等的。

那么类型转换如何解决这个问题呢? {{1}}

7 个答案:

答案 0 :(得分:13)

您正在将浮点数与双精度数进行比较。文字1.7是双重的。

你已经将它存储在浮点数中,浮点数的精度可能低于双精度数,因此me == 1.7将1.7作为浮点数(提升为双精度数)与1.7作为双精度数进行比较。

在这种情况下,me == 1.7f应该将它们进行比较,或者将me更改为双double me = 1.7;

在一般情况下,您希望使用epsilon比较相等,如@duffymo所示。

另外,Obligatory read

答案 1 :(得分:2)

答案 2 :(得分:2)

1.7的最接近的表示形式对于float和double是不同的,因此转换为float通常应该产生相同的数字。

无法比较浮点数的一个主要原因是,对于实数和整数有效的标识不一定适用于浮点因为舍入 - 即(x + y)+ z和x +(y + z)通常可以是不同的(请注意,以这种方式编写它们通常不会改变编译器的行为,但是您可以通过执行编译器不会优化的操作来诱导顺序。)

例如,(100 - (100 - .0000000001))!= .00000000001使用IEEE-754加倍,即使数学表明它们应该相等。所以应该产生.00000000001的计算将稍微偏离。这尤其是更复杂计算的问题,例如线性代数,其中答案可能是数千次加法和减法的结果,每次加法和减法都会增加浮点舍入误差。

如果你真的不明白发生了什么,那么IEEE-754浮点可能非常棘手。

我推荐优秀的“每个计算机科学家应该知道的浮点运算”:http://docs.sun.com/source/806-3568/ncg_goldberg.html

答案 3 :(得分:2)

假设IEEE-754表示,文字1.7f和1.7代表以下值:

1.7f == 1.7000000476837158203125
1.7  == 1.6999999999999999555910790149937383830547332763671875

显然,这些值并不相同,因此它们比较为假。

答案 4 :(得分:1)

浮动我= 1.7f;

答案 5 :(得分:0)

这是一个关于numerical analysis的表示问题,因为你有一个有限的位来表示所表示的数字并不完全等于你所指的数字,它只是近似于最接近的数字数字可以代表你的位数。 阅读here

答案 6 :(得分:0)

1.7在比较中自动转换为双倍。因此,您将1.7与1.7d进行比较,这可能因某些(双)机器epsilons而不同。