我想找出为什么我得到的结果是 0.0?
这是我的代码:
public void rechneFunktion() {
double x1 = Math.pow(10, 20);
double x2 = 1223.0;
double x3 = Math.pow(10, 18);
double x4 = Math.pow(10, 15);
double x5 = 3.0;
double x6 = Math.pow(10, 12) * (-1);
double y1 = Math.pow(10, 20);
double y2 = 2.0;
double y3 = Math.pow(10, 22) * (-1);
double y4 = Math.pow(10, 13);
double y5 = 2111.0;
double y6 = Math.pow(10, 16);
double erg = (x1 * y1) +(x3 * y3)+ (x2 * y2) + (x4 * y4)+(x5 * y5)+(x6 * y6);
System.out.println(erg);
}
最佳答案
您使用的 double
值只有大约 17-18 位精度(53 位)。因此,当您将小值和大值相加时,大值不会受到影响。然后减去较大的值,留下 0
。
从数学上讲,您正在计算表达式:
1020 x 1020 + 1018 x (-1022) + 1,223 x 2 + 1015 x 1013 + 3 x 2,111 + (-1022) * 1016
简化:
1040 - 1040 + 2,446 + 1028 + 6,333 - 1028
从数学上讲,1040 和 -1040 相互抵消,1028 和 -1028 也相互抵消sup>,剩下 8,779。
由于double
的精度有限,“小”值会被消除。以下是 Java 中求和的每一步所发生的情况:
- 1040 =>
1.0E40
- - 1040 =>
0.0
- + 2,446 =>
2446.0
- + 1028 =>
1.0E28
由于精度问题,2446
被删除。 - + 6,333 =>
1.0E28
6333
由于精度问题而被删除。 - -1028 =>
0.0
要获得 8779.0
的正确值,请先进行取消,而不是在总和当前太大而无法适应精度时添加“小”值。
double erg = (x1 * y1) +(x3 * y3)+ (x4 * y4) + (x6 * y6) + (x2 * y2) +(x5 * y5);
关于java - Java 中具有双值的有限机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26492620/