在 DO 循环中执行求和时出现 Fortran 浮动错误?

Fortran Floating Error while performing summation within DO loop?

我在数组 (n) 中有四个双精度实数(n1、n2、n3 和 n4)。

奇怪的是当我计算这四个数字的总和时 一个 DO 循环然后直接计算总和我没有得到相同的确切数字!

请注意,我正在更改数字的顺序。例如,在 Do 循环中,我执行 n1 + n2 + n3 + n4,但在直接求和中,我执行 n1 + n3 + n2 + n4。两者应该给出相同的数字,但是当我减去这两个结果时,我没有得到零,而是得到一个非常小的数字 (x10^-21)!

这是我的代码:

PROGRAM SumFourNo
REAL(KIND=DP) :: n(4), n_sum
INTEGER       :: i

n(1) = 9.259259259259259E-006
n(2) = 4.629629629629630E-006
n(3) = 9.259259259259259E-006
n(4) = 4.629629629629630E-006
n_sum = 0.0_DP

DO i = 1 , 4
    n_sum = n_sum + n(i)
ENDDO

WRITE(*,*) 'Check =', (n(1)+n(3)+n(2)+n(4)) - n_sum

ENDPROGRAM SumFourNo

当然,我的代码比这大得多,但我不想让您感到困惑,所以我只向您展示了它的这一部分。

经典的舍入误差问题。浮点加法不遵守通常的数学规则。特别是,(a+b)+c = a+(b+c) 不成立。

如果 10^-21 对您来说是一个太大的错误,请查看 Kahan 求和。简而言之,它跟踪求和中累积的舍入误差。