【问题标题】:Strange output when comparing same float values?比较相同的浮点值时输出奇怪?
【发布时间】:2017-06-01 04:03:59
【问题描述】:

Comparing Same Float Values In C

strange output in comparison of float with float literal

Float addition promoted to double?


我在浮点数上阅读了上述链接,但甚至得到了奇怪的输出。

#include<stdio.h>
int main()
{
    float x = 0.5;

    if (x == 0.5)
        printf("IF");

    else if (x == 0.5f)
        printf("ELSE IF");

    else
        printf("ELSE");
}

现在,根据促销规则,“ELSE IF”不是必须要打印吗?

但是,这里打印的是“IF


编辑:是不是因为 0.5 = 0.1 在二进制中,然后一切都是 0 并且精度损失因此没有效果,所以比较 IF 返回 true。

如果是 0.1、0.2、0.3、0.4、0.6、0.7....,那么 Else If 块返回 true。


请原谅我问同样的问题,因为我从上面的链接中读到,永远不能进行浮点比较。

但是,这种意外行为的原因是什么?

【问题讨论】:

  • The usual arithmetic conversion rules 表示如果其中一个操作数是 double,则另一个操作数将转换为 double。所以条件x == 0.5 实际上是(double) x == 0.5 这当然是真的。但是,由于计算机上的浮点值存在问题(请参阅 Is floating point math broken? 了解详细信息),很少有值是这样的。
  • 我仍然认为你的问题有点不清楚,但如果我理解正确(并接受 Gerhardh 提供的答案),那么是的,你是对的。
  • @Someprogrammerdude 是的,这正是我推断的。谢谢!!
  • “它们永远不准确。” 这是常见的误解。对于它们被设计用来表示的值,浮点数与整数一样准确。只是程序员经常抱有错误的期望,C 的各种类型转换规则都无济于事。

标签: c floating-point precision


【解决方案1】:

浮点数永远不准确。

这个说法是错误的。有些浮点数是准确的,例如 1.0、12345.0、12345.5、-2.25。所有这些数字都可以表示为整数除以 2 的幂。所有不能表示的数字也不准确。

在您的特定情况下,float x = 0.5 导致 x 具有值 1.00000000 * 2^-1。当你把这个和double 0.5比较时,两个操作数都转换为double,所以比较就变成了1.000000000000000 * 2^-1 == 1.000000000000000 * 2^-1,就成功了。

对于float x = 0.1,它看起来不同。该值存储为1.01010101 * 2^-3(或类似名称)。请注意,这已经不准确了。当您将其与double 0.1 进行比较时,浮点数在末尾用零扩展,比较变为1.010101010000000 * 2^-3 == 1.010101010101010 * 2^-3,结果失败。

【讨论】:

  • 谢谢!!得到了我要找的东西!!但是,我不能投票。
  • 我实际上会说所有浮点数都是准确的。它以不准确的十进制表示法表示它们。问题不在于数字,问题在于将它们转换为十进制字符串/从十进制字符串转换。如果我们只将整数表示为 3 的分数,它们也会“不准确”。
【解决方案2】:

当您阅读了有关浮点类型和比较问题的链接时,您可能期望在转换过程中对 0.5 进行四舍五入,因此比较应该会失败。 但是 0.5 是 2 的幂,并且可以完美地表示,而无需在 float 或 double 类型变量中进行任何舍入。 因此比较结果为 TRUE。

编辑您的问题后: 是的,如果您采用 0.1 或您提到的其他值之一,您应该进入 else 部分。

【讨论】:

    【解决方案3】:

    第一个if 语句的计算结果为true,因此打印了IF。甚至没有检查其他表达式。

    【讨论】:

    • 我认为 OP 明白这一点。
    • 他添加的链接表明他的实际问题是为什么条件评估为TRUE
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多