surprising double comparison
本问题已经有最佳答案,请猛点这里访问。
我把代码执行结果搞砸了。
代码:
输出:
1 2 | true false |
号
我知道0.2和0.3不能转换为二进制正确。
为什么我看到不同的结果?
更新:
在没有编译器的情况下,我能预测类似问题的结果吗?
1 |
输出
1 | 0.30000000000000004 |
号
浮点运算存在舍入误差。有些值不能用基数2表示,不能依赖于比较浮点数。基-2中的0.1类似于基-10中的1/3。
您可以看到下面的链接
每一个计算机科学家都应该知道什么是浮点运算
您看到的事实是,浮点值不是非常精确,例如,您不应该使用
1 2 3 |
。
其中epsilon是一些非常小的浮点值
你不能依靠
P.S.下面的测试是在
1 2 3 4 5 6 7 8 | cout << (0.1==0.1) << endl; // true cout << (0.2==0.1+0.1) << endl; // true cout << (0.3==0.1+0.1+0.1) << endl; // false cout << (0.4==0.1+0.1+0.1+0.1) << endl; // true cout << (0.5==0.1+0.1+0.1+0.1+0.1) << endl; // true cout << (0.6==0.1+0.1+0.1+0.1+0.1+0.1) << endl; // true cout << (0.7==0.1+0.1+0.1+0.1+0.1+0.1+0.1) << endl; // true cout << (0.8==0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1) << endl; // false |
PHP给出了:
1 2 3 4 5 6 7 8 9 10 | <?php printf("%0.20f ", 0.1+0.1); printf("%0.20f ", 0.1+0.1+0.1); ?> 0.20000000000000001110 0.30000000000000004441 |
和
1 2 3 4 5 6 7 8 9 10 | <?php echo 0.2==0.1+0.1?"true ":"false "; echo 0.3==0.1+0.1+0.1?"true ":"false "; ?> true false |
。
第一个"真"的重演:
1 2 3 4 5 6 7 8 9 10 11 12 | <?php printf("%0.20f ", 0.1+0.1); printf("%0.20f ", 0.1+0.1+0.1); echo" "; printf("%0.20f ", 0.2); printf("%0.20f ", 0.3); ?> |
产量
1 2 3 4 5 | 0.20000000000000001110 0.30000000000000004441 0.20000000000000001110 0.29999999999999998890 |
。