【问题标题】:C coding, unexpected behaviour when comparing float value [duplicate]C编码,比较浮点值时的意外行为[重复]
【发布时间】:2017-01-24 13:23:50
【问题描述】:

比较浮点值时出现意外行为,我知道浮点数可能存在舍入精度问题,但这里的数字非常具体地反映了这些问题。

#include <stdio.h>
int main()
{
    float alpha = 0.0f;
    int finish = 0;

    while (finish == 0)
    {
        alpha += 0.05f;

        if (alpha > 1.0f)
        {
            printf("%f", alpha);    // Expected result: 1.05f, actual result: 1.0f
            finish = 1;
        }
    }

    return 0;
}

实际上,当 alpha = 1.0f 时,条件进入。无法理解这种行为...

我正在 Windows 10(在 32 位和 64 位测试)、Intel i5 处理器上使用 MinGW (GCC 5.3.0) 进行编译。

【问题讨论】:

  • 如果您要打印alpha 带有更多有效数字(例如printf("%.7f\n", alpha);),那么您会立即看到问题:ideone.com/zwQW7e
  • 您必须知道 0.05f 的常数是否比准确表示 0.05 的无限位流略小或略大。据推测,它稍微大一点。
  • 看看这个(这是我用来构建答案的):exploringbinary.com/floating-point-converter
  • @Bathsheba:考虑到“做我的功课”和“运算符/语句 xyx 是什么意思”问题的数量,你是对的。确实只有少数 C 题没有重复。问题更多的是找到重复,因为新手使用错误/误导性的短语非常有创意。哦,我们也应该从海报中得到一些理由。否则,他们将无法在编程中取得任何进展。

标签: c gcc floating-point floating-accuracy


【解决方案1】:

(如果我可以将答案限制为 IEEE754 浮点)。

没有像0.05 这样的float最近的数可以表示为

0.0500000007450580596923828125

所以发生的情况是,比您认为的值更大的值被添加到alpha,这足以只是将其推过1.0f标记(出于兴趣,可以精确表示。)

print 中的默认格式是将略大于1.0f 的数字舍入回1.0f

总而言之,这一切都是由于二进制浮点通常没有精确的十进制表示。

【讨论】:

  • 我不同意,尽管建议 OP 研究副本。即使掌握了浮点知识,也很高兴对这种特殊情况进行解释。 (对于它的价值,我可能会关闭 2 或 3 个浮点问题,这些问题与您每周确定的问题重复。)
猜你喜欢
  • 1970-01-01
  • 2012-07-17
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
  • 2013-07-02
  • 2011-10-24
相关资源
最近更新 更多