2015-01-30 7 views
0

배열 (n)에 4 개의 배정도 실수 (n1, n2, n3, & n4)가 있습니다.Fortran Floating DO 루프 내에서 합산을 수행하는 동안 오류가 발생 했습니까?

내에서이 4 개의 숫자의 합계를 계산할 때 DO 루프가 발생하고 직접 합계를 계산하면 이상한 숫자가 발생합니다.

숫자의 순서가 변경된다는 점에 유의하십시오. 예를 들어 Do 루프 중에는 n1 + n2 + n3 + n4가되지만 직접 합계에서는 n1 + n3 + n2 + n4가됩니다. 둘 다 같은 수를 주어야하지만 두 결과를 뺄 때 0이 아니고 매우 작은 수 (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

부동 소수점 산술은 실제 수학과 같은 연관성이 없습니다. 합산의 순서는 중요하며 일반적인 경우에 정확한 결과를 얻는 방법에 대한 많은 수의 문서가 작성되었습니다. 이 글은 [부동 소수점 연산에 관한 입문] (0120-367-301)을 참조하십시오. – njuffa

+1

'10^-21 '의 크기가 약 10^-6 인 숫자는 15 번째 유효 숫자의 차이입니다. 바로 64 비트 IEEE 부동 소수점 정밀도의 한계입니다. –

답변

2

클래식 반올림 오류 문제. 부동 소수점 추가는 일반적인 수학적 규칙을 따르지 않습니다. 특히 (a+b)+c = a+(b+c)은 보유하지 않습니다.

10^-21이 너에게 많은 오류가있는 경우 Kahan 합계를 찾으십시오. 즉, 합계에서 누적 된 반올림 오류를 추적합니다.

+0

감사합니다. Kahan의 합계가 나를 위해 오류를 제거했습니다. – user3203131