浮点数与C值的比较-IDC帮帮忙

预测以下C程序的输出。

#include<stdio.h>
int main()
{
    float x = 0.1;
    if (x == 0.1)
        printf("IF");
    else if (x == 0.1f)
        printf("ELSE IF");
    else
        printf("ELSE");
}

上述程序的输出为“ ELSE IF ”,表示表达式“x == 0.1”返回false,表达式“x == 0.1f”返回true。

让我们考虑以下程序,了解上述输出背后的原因。

#include<stdio.h>
int main()
{
   float x = 0.1;
   printf("%d %d %d", sizeof(x), sizeof(0.1), sizeof(0.1f));
   return 0;
}
在典型的C编译器上,上述程序的输出为“ 4 8 4 ”。
它实际上打印浮动的大小,双倍的大小和浮动的大小。

表达式中使用的值被视为double(双精度浮点格式),除非在末尾指定了'f'。所以表达式“x == 0.1”在右侧有一个double和float,它们在左侧以单精度浮点存储存储。在这种情况下,持股量提升一倍(见本)。双精度格式比单精度格式使用更多位来实现精度。
0.1二进制等效值10可被写为(0.00011001100110011 ...)2,其将上升到无穷大(参见本文章了解转换的更多信息)。由于浮点数的精度小于双精度因此在某个点之后(浮点数为23,双精度值为52),因此会截断结果。因此,在将float提升为double之后(在比较时),编译器将用零填充剩余的位。因此,我们得到不同的结果,其中两者的十进制等价物将是不同的。例如,

在浮动 
=>(0.1)10 =(0.00011001100110011001100)2
在浮动推广后的双倍...(1)
=>(0.1)10 =(0.00011001100110011001100000000000000000 ...)2
                                      ^填充零在这里
在没有促销的双倍...(2)
=>(0.1)10 =(0.0001100110011001100110011001100110011001100110011001)2

因此我们可以看到两个方程的结果是不同的。
因此'if'语句永远不会被执行。

请注意,当值(如0.1)使用比单精度位更多的精度位时,将float提升为double只会导致不匹配。例如,以下C程序打印“IF”。

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

输出:

如果

这里二进制当量为0.5 10是(0.100000 ...)2
(浮点和双精度都不会丢失精度)。因此,如果编译器在提升时填充额外的零,那么我们将在比较中得到相同的结果(左侧和右侧的十进制等效值)(x == 0.5)。
您可以参考来浮点表示—基础知识表示浮点数。