java - Java 中具有双值的有限机

标签 java double

我想找出为什么我得到的结果是 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 中求和的每一步所发生的情况:

  1. 1040 => 1.0E40
  2. - 1040 => 0.0
  3. + 2,446 => 2446.0
  4. + 1028 => 1.0E28 由于精度问题,2446 被删除。
  5. + 6,333 => 1.0E28 6333 由于精度问题而被删除。
  6. -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/

相关文章:

java - 从 HashMap 获取值并填充 Java 对象

java - Java中如何在字符串中插入字符

c++ - 双数输出被截断

c# - 扩展大值

c - 如何获取函数内 double 值的绝对值(不使用 math.h)

java - 从 JSON 中读取不带小数点的浮点或 double 值

java - Tapestry5 中的页面重定向

java - 在 Struts2 中维护多个 JDBC 连接

java - 从文件中读取并存储

java - java中十进制数的总和