比较浮动和双重
#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
是。
因此, float
和double
表示将保持略微不同的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
这显然是相同的数字。