これらの両方のステートメントが同じ値を出力しないのはなぜですか?
結果は同じではありません。
一部の浮動小数点値を正確に表現できないことはわかっています。
したがって、演算の結果は、使用する値の表現エラーの量に依存する可能性があると想定する必要があります。
for (long l = 1; l <= 1e16; l *= 10) {
double a = l + 2;
double b = l + 1.1;
System.out.println(a + " - " + b + " is " + (a - b));
}
値が大きくなるにつれて表現誤差が大きくなり、0.9 の結果と比較して大きくなります。
3.0 - 2.1 is 0.8999999999999999
12.0 - 11.1 is 0.9000000000000004
102.0 - 101.1 is 0.9000000000000057
1002.0 - 1001.1 is 0.8999999999999773
10002.0 - 10001.1 is 0.8999999999996362
100002.0 - 100001.1 is 0.8999999999941792
1000002.0 - 1000001.1 is 0.9000000000232831
1.0000002E7 - 1.00000011E7 is 0.900000000372529
1.00000002E8 - 1.000000011E8 is 0.9000000059604645
1.000000002E9 - 1.0000000011E9 is 0.8999999761581421
1.0000000002E10 - 1.00000000011E10 is 0.8999996185302734
1.00000000002E11 - 1.000000000011E11 is 0.899993896484375
1.000000000002E12 - 1.0000000000011E12 is 0.9000244140625
1.0000000000002E13 - 1.00000000000011E13 is 0.900390625
1.00000000000002E14 - 1.000000000000011E14 is 0.90625
1.000000000000002E15 - 1.0000000000000011E15 is 0.875
1.0000000000000002E16 - 1.0000000000000002E16 is 0.0
表現エラーが非常に大きくなると、操作は何もしません。
for (double d = 1; d < Double.MAX_VALUE; d *= 2) {
if (d == d + 1) {
System.out.println(d + " + 1 == " + (d + 1));
break;
}
}
for (double d = 1; d < Double.MAX_VALUE; d *= 2) {
if (d == d - 1) {
System.out.println(d + " - 1 == " + (d - 1));
break;
}
}
版画
9.007199254740992E15 + 1 == 9.007199254740992E15
1.8014398509481984E16 - 1 == 1.8014398509481984E16