2015-01-30 3 views
0

У меня есть четыре действительных числа с двойной точностью (n1, n2, n3, & n4) в массиве (n).Fortran Floating Error при выполнении суммирования в цикле DO?

Странная вещь, когда я вычисляю сумму этих четырех чисел в пределах цикла 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 

Конечно мой код путь больше, чем это, но я не хочу, чтобы сбить вас с толку, так что я показал вам только эту часть.

+0

Арифметика с плавающей точкой не является ассоциативной, как реальная математика. Порядок суммирования имеет место, и было написано большое количество статей о том, как добиться точных результатов в общем случае. Возможно, вы захотите прочитать это [праймер по арифметике с плавающей точкой] (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – njuffa

+1

Обратите внимание, что разница в '10^-21 'в числах с величиной около 10^-6' является разницей в 15-м значении, прямо на пределе 64-битной точности с плавающей точкой IEEE. –

ответ

2

Ошибка. Добавление с плавающей запятой не подчиняется обычным математическим правилам. В частности, (a+b)+c = a+(b+c) не выполняется.

Если 10^-21 является для вас слишком большой ошибкой, обратите внимание на суммирование Кахана. Короче говоря, это отслеживает накопленные ошибки округления в суммировании.

+0

Спасибо, суммирование Kahan устранило ошибку для меня. – user3203131