我搞乱了代码执行结果。
代码:
System.out.println(0.2==0.1+0.1);
System.out.println(0.3==0.1+0.1+0.1);
输出:
true
false
我知道0.2和0.3无法转换为二进制校正。
为什么我会看到不同的结果?
更新
我可以在没有编译器的情况下预测类似问题的结果吗?
答案 0 :(得分:9)
System.out.println(0.1+0.1+0.1);
输出
0.30000000000000004
浮点算术有一个舍入误差。有些值无法在基数2中表示,您不能依赖于比较浮点数。基础-2中的0.1与基础-10中的1/3相似。
您可以看到以下链接
What Every Computer Scientist Should Know About Floating-Point Arithmetic
答案 1 :(得分:2)
您所看到的是浮点值不是很准确,您不应该使用==
运算符来比较它们。对于比较,你应该使用epsilon比较,即。对于两个浮点值f1和f2
if (Math.abs(f1 - f2) < EPSILON ) {
// they are equal
}
EPSILON是一个非常小的浮点值
答案 2 :(得分:0)
PHP给出了这个:
<?php
printf("%0.20f\n", 0.1+0.1);
printf("%0.20f\n", 0.1+0.1+0.1);
?>
0.20000000000000001110
0.30000000000000004441
和
<?php
echo 0.2==0.1+0.1?"true\n":"false\n";
echo 0.3==0.1+0.1+0.1?"true\n":"false\n";
?>
true
false
第一个成为“真实”的原因:
<?php
printf("%0.20f\n", 0.1+0.1);
printf("%0.20f\n", 0.1+0.1+0.1);
echo "\n";
printf("%0.20f\n", 0.2);
printf("%0.20f\n", 0.3);
?>
输出
0.20000000000000001110
0.30000000000000004441
0.20000000000000001110
0.29999999999999998890
答案 3 :(得分:0)
您不能依赖==
才能正常使用float
个数字,这些数字的结果不可靠,因为它们无法在计算机上准确表示。如果您想检查两个float
数字是否相等,请改用fabs(a-b) < epsilon
。
P.S。以下测试位于C++
下,这给出了惊人的结果(只是为了表明它是多么不可靠的乐趣):
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