【问题标题】:Understanding float variable comparison in if() [duplicate]了解 if() 中的浮点变量比较 [重复]
【发布时间】:2013-08-22 09:58:22
【问题描述】:

找不到下面这段代码的原因:

#include <stdio.h>
int main()
{
    float f = 0.1;
    if (f == 0.1)
      printf("True");
    else
      printf("False");
    return 0;
}

输出为假。

#include <stdio.h>
int main()
{
    float f = 0.1;
    if (f == (float)0.1)
      printf("True");
    else
      printf("False");
    return 0;
}

现在显示正确的输出。这背后的原因是什么?

还有这种行为的原因是什么。

#include <stdio.h>
main()
{
    int n = 0, m = 0;
        if (n > 0)
            if (m > 0)
                    printf("True");
        else 
            printf("False");
}

【问题讨论】:

  • 请不要比较浮点数是否相等。浮点数几乎从不相等。
  • 复制数十次。
  • ..and C tag 开启了今天的“恼人的问题”竞赛,与一个古老的经典。 (信用:Martin James
  • @H2CO3 感谢您指出这一点。我之前搜索过没有得到相同的结果。我来看看答案。
  • @Megharaj 不客气 - 你也可以从阅读 this 经常被引用的文章中受益。

标签: c floating-point floating-point-conversion


【解决方案1】:

0.1 文字是double。你在这里失去精度float f = 0.1;

你可以说我们在比较过程中再次失去了精度,那么为什么f == 0.1 不是真的呢?因为float 延伸到double,而不是相反。在 C 中,较小的类型总是扩展到较大的类型。

简化你的例子,我们可以说double(float(1.0)) != 1.0

可能的解决方案:

  • 使用double 而不是float 作为f 的类型。
  • 在第二个示例中使用强制转换
  • 使用 float 文字 - 将所有 0.1 替换为 0.1f

更好的解决方案

浮点变量在比较方面有很多问题。它们,包括这个,可以通过定义你自己的比较函数来解决:

bool fp_equal(double a, double b, double eps = FLT_EPSILON) {
  return fabs(a - b) < fabs(eps * a);
}

问题的第二部分:

为什么答案为假是因为else 部分始终对应于最里面的if 块。所以你被格式化弄糊涂了,代码相当于:

#include <stdio.h>

int main()
{
    int n = 0, m = 0;
    if (n > 0) {
        if (m > 0) {
            printf("True");
        }
        else {
            printf("False");
        }
    }
}

【讨论】:

  • 感谢您快速正确的回答。
  • 另一种解决方案是使用浮点文字 f, float f = 0.1f; if (f == 0.1f) ...
  • @AlterMann,它写在我的 asnwer 中。请注意第三个要点。
  • @sasha 请你回答我在问题中的第三个例子(刚刚编辑)
  • 在进行此类比较时,您可能应该考虑浮点值的大小。 c-faq.com/fp/fpequal.html
【解决方案2】:

回答你的第二个问题(第三个例子):

根据您的缩进,代码没有按照您的预期执行:

#include <stdio.h>
main()
{ 
    int n = 0, m = 0;
        if (n > 0)
            if (m > 0)
                 printf("True");
        else 
            printf("False");
}

这里else属于内部if,所以等于

#include <stdio.h>
main()
{ 
    int n = 0, m = 0;
        if (n > 0) {
            if (m > 0) {
                 printf("True");
            } else {  
                 printf("False");
            }
        }
}

但我认为你的意思是:

#include <stdio.h>
main()
{ 
    int n = 0, m = 0;
        if (n > 0) {
            if (m > 0) {
                 printf("True");
            }
        } else {  
            printf("False");
        }
}

这是一个很好的例子,说明为什么应该在 if 语句中始终使用用户括号。

【讨论】:

  • 和适当的缩进。以及main 的返回类型。
  • @Ligthness 绝对正确
猜你喜欢
  • 2012-10-26
  • 1970-01-01
  • 2011-10-24
  • 1970-01-01
  • 2015-09-06
  • 2023-04-05
  • 2015-03-19
相关资源
最近更新 更多