比较浮动和双重

#include  int main(void){ float a = 1.1; double b = 1.1; if(a == b){ printf("if block"); } else{ printf("else block"); } return 0; } 

打印:else阻止

 #include  int main(void){ float a = 1.5; double b = 1.5; if(a == b){ printf("if block"); } else{ printf("else block"); } return 0; } 

打印:如果阻止

这背后的逻辑是什么?

编译使用:gcc-4.3.4

这是因为1.1在二进制浮点中不能完全表示。 但1.5是。

因此, floatdouble表示将保持略微不同的1.1值。

当写成二进制浮点时,这正是区别的:

 (float) 1.1 = (0.00011001100110011001101)₂ (double)1.1 = (0.0001100110011001100110011001100110011001100110011010)₂ 

因此,当你比较它们(并且float版本被提升)时,它们将不相等。

必读: 每个计算机科学家应该知道浮点运算

二进制中1.1十进制的精确值是非结束分数1.00011001100110011001100(1100)….双常数1.1是该尾数的 53位截断/近似值。 现在转换为float时,尾数将仅以24位表示。

float转换回double时,尾数现在又回到53位,但超过24的数字的所有内存都会丢失 – 该值为零扩展,现在您正在进行比较(例如,取决于舍入行为)

 1.0001100110011001100110011001100110011001100110011001 

 1.0001100110011001100110000000000000000000000000000000 

现在,如果您使用1.5而不是1.1;

1.5十进制正好是二进制的1.1 。 它可以精确地呈现在2位尾数中,因此即使24位浮点数也是夸张的…你所拥有的是

 1.1000000000000000000000000000000000000000000000000000 

 1.10000000000000000000000 

后者,零扩展到双倍

 1.1000000000000000000000000000000000000000000000000000 

这显然是相同的数字。