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

标签 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;
}

输出为假。

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

最佳答案

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);
}
<小时/>

问题的第二部分:

为什么答案是 false 是因为 else 部分总是对应于最里面的 if block 。所以你对格式感到困惑,代码相当于:

#include <stdio.h>

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

关于c - 了解 if() 中的浮点变量比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18377240/

相关文章:

c - C的流中字符的含义

c# - 如何测试负零?

c - scanf 的问题,C. 浮点异常

c - sscanf 使用 c 进行 float

c++ - 使用 C++ 输入运算符读取 float

c++ - OS X IPC 在 C 中获取进程 ID

c - 炸弹实验室phase_3,不知道如何找到开关 block 的起始地址

c - 使 GNU 缩进正确处理结构文字

c - 这个数字是否有超过 D 位小数?