【问题标题】:Why Floating point numbers cant be compared? [duplicate]为什么浮点数不能比较? [复制]
【发布时间】:2010-08-31 09:36:25
【问题描述】:

可能重复:
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

【问题讨论】:

标签: c++ c floating-point


【解决方案1】:

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

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

在这种情况下,me == 1.7f 应该让它们比较相等,或者将 me 更改为双精度 double me = 1.7;

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

另外,Obligatory read

【讨论】:

  • 好的。嗯,答案很好,但是 C++/C 中的规则是在比较时数字会自动提升为双倍吗?
  • @Shubham 一个普通的十进制数总是双倍的;您应该添加f 使其成为浮动
【解决方案2】:

【讨论】:

【解决方案3】:

float 和 double 最接近 1.7 的表示形式不同,因此转换为浮点数通常会产生相同的数字。

您无法比较浮点数的主要原因之一是适用于实数和整数的恒等式不一定适用于浮点数,因为四舍五入 - 即 (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

【讨论】:

  • 不幸的是,恕我直言,在大多数语言中,如果比较器运算符的一个操作数是double,另一个运算符通常会默默地转换为double;恕我直言,唯一应该隐式转换为double在该上下文中的类型是整数类型,其值都可以精确表示为double。在大多数情况下,(float)someDouble == someFloatsomeDouble == (double)someFloat 更有意义,但是因为让someFloat == someDouble 产生该行为会阻止== 定义等价关系,所以这将是一个糟糕的编译器默认值。
  • 另一方面,(float)someDouble == someFloat 通常在语义上更有意义这一事实表明,以someDouble == (double)someFloat 执行相等检查也不是一个好的默认值。恕我直言,正确的做法是要求程序员明确将一个操作数转换为另一个操作数的类型;如果 f1==d1 和 f1==d2,但 d1!=d2,那将是令人惊讶的。另一方面,当 d1!=d2 时具有 f1==(float)d1 和 f1==(float)d2 一点也不奇怪。
【解决方案4】:

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

1.7f == 1.7000000476837158203125
1.7  == 1.6999999999999999555910790149937383830547332763671875

显然,它们不是相同的值,因此它们比较为假。

【讨论】:

    【解决方案5】:

    漂浮我 = 1.7f;

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-03-03
          • 1970-01-01
          • 2013-07-16
          • 1970-01-01
          • 2011-10-24
          • 1970-01-01
          相关资源
          最近更新 更多