了解if()中的浮点变量比较

时间:2013-08-22 09:58:22

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

无法找到以下代码的原因:

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

输出为false。

#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");
}

2 个答案:

答案 0 :(得分:6)

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");
        }
    }
}

答案 1 :(得分: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语句中包含用户括号。