以下程序输出This No. is not same
。当两个数字相同时,为什么会这样做?
void main() {
float f = 2.7;
if(f == 2.7) {
printf("This No. is same");
} else {
printf("This No. is not same");
}
}
答案 0 :(得分:7)
为什么两个数字相同时都会这样做?
数字不是相同的值。
double
可以表示完全通常大约2 64 不同的值。
float
可以代表完全通常约2 32 不同的值。
2.7不是其中一个值 - 给定浮点编码的二进制性质与十进制文本2.7
的一些近似值编译器将2.7
转换为最近的可表示double
或
2.70000000000000017763568394002504646778106689453125
给出double
的典型binary64表示。
下一个最好的double
是
2.699999999999999733546474089962430298328399658203125。
知道超过17位有效数字的精确值会降低实用性。
将值分配给float
时,它将成为最接近的可表示float
或
2.7000000476837158203125。
2.70000000000000017763568394002504646778106689453125不等于2.7000000476837158203125。
如果编译器使用与decimal32/decimal64完全相同的float/double
<{1>}的2.7
,则代码将作为预期的OP工作。使用基础小数格式的double
表示很少见。更常见的是,基础double
表示是基数2,编程时需要考虑这些转换工件。
如果代码为float f = 2.5;
,则使用二进制或十进制基础格式的float
和double
值会使if (f == 2.5)
为真。与高精度double
相同的值可表示完全为低精度float
。
(假设binary32 / binary64浮点)
double
有53位有效位,float
有24位。关键是如果作为double
的数字的最低有效位(53-24)设置为0,则转换为float
,它与float
或double
具有相同的数值。 1
,2.5
和2.7000000476837158203125
等数字可以实现这一目标。 (此处忽略范围,次正常和NaN问题。)
这就是为什么精确浮点比较通常仅在特定情况下进行的原因。
答案 1 :(得分:1)
检查此程序:
#include<stdio.h>
int main()
{
float x = 0.1;
printf("%zu %zu %zu\n", sizeof(x), sizeof(0.1), sizeof(0.1f));
return 0;
}
输出为4 8 4
。
除非在结尾指定double (double precision floating point format)
,否则表达式中使用的值将被视为f
。因此表达式“x==0.1″
在右侧有一个double和float,它们在左侧以单精度浮点格式存储。
在这种情况下float is promoted to double
。
双精度格式使用比单精度格式更多的位用于精度。
在您的情况下,添加2.7f
以获得预期结果。
答案 2 :(得分:0)
2.7
中的文字f == 2.7
已转换为double
,这就是2.7
不等于f
的原因。