预测以下C程序的输出。
C
#include
int main()
{
float x = 0.1;
if (x == 0.1)
printf("IF");
else if (x == 0.1f)
printf("ELSE IF");
else
printf("ELSE");
}
C
#include
int main()
{
float x = 0.1;
printf("%d %d %d", sizeof(x), sizeof(0.1), sizeof(0.1f));
return 0;
}
C
#include
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 ”,这意味着表达式“ x == 0.1”返回false,表达式“ x == 0.1f”返回true。
让我们考虑以下程序,以了解上述输出背后的原因。
C
#include
int main()
{
float x = 0.1;
printf("%d %d %d", sizeof(x), sizeof(0.1), sizeof(0.1f));
return 0;
}
The output of above program is "4 8 4" on a typical C compiler.
It actually prints size of float, size of double and size of float.
除非在末尾指定“ f”,否则在表达式中使用的值将被视为double(双精度浮点格式)。因此,表达式“ x == 0.1”在右侧具有一个double值,并且在左侧具有以单精度浮点格式存储的float值。在这种情况下,浮点数将增加一倍(请参阅此内容)。双精度格式比单精度格式使用更多位进行精度。
二进制等效值0.1 10可以写为(0.00011001100110011…) 2 ,该值一直到无穷大(有关转换的更多信息,请参阅本文)。由于float的精度小于double的精度,因此在某个点之后(float中为23,double中为52),它将截断结果。因此,在将float提升为double后(在比较时),编译器将用零填充其余位。因此,我们得到了不同的结果,其中两者的十进制当量会有所不同。例如,
In float
=> (0.1)10 = (0.00011001100110011001100)2
In double after promotion of float ...(1)
=> (0.1)10 = (0.00011001100110011001100000000000000000...)2
^ padding zeroes here
In double without promotion ... (2)
=> (0.1)10 = (0.0001100110011001100110011001100110011001100110011001)2
Hence we can see the result of both equations are different.
Therefore 'if' statement can never be executed.
请注意,仅当值(如0.1)使用的精度位比单精度的位多时,将float提升为double才会导致不匹配。例如,以下C程序打印“ IF”。
C
#include
int main()
{
float x = 0.5;
if (x == 0.5)
printf("IF");
else if (x == 0.5f)
printf("ELSE IF");
else
printf("ELSE");
}
输出:
IF
此处的0.5 10的二进制当量为(0.100000…) 2
(浮点型和双精度型都不会损失精度)。因此,如果编译器在升级时填充额外的零,那么在比较时,我们将在左侧和右侧的十进制等效值中得到相同的结果(x == 0.5)。
您可以参考“浮点表示法-基础知识”以表示浮点数。