- This topic has 2개 답변, 2명 참여, and was last updated 10 years, 11 months 전에 by inmyta27.
-
글쓴이글
-
-
inmyta27회원
안녕하세요 다름이 아니라 값들의 평균을 구하는 내용을 다음과 같이 코딩해보았는데..
openr,5, file11for ii=0, line_count-1 do begin
readf,5, mi,inter, n_d
minu[ii]=mi
interval[ii]=inter
nd[ii]=n_dendfor
close,5
for jj=0,29 do begin
sum_nd=0.
sum_nu=0.kk=(0.1+(0.2*jj))
for ii=0, line_count-1 do begin
if (interval[ii] eq kk) then begin
sum_nd=sum_nd+nd[ii]
sum_nu=sum_nu+1.endif
endfor
avg_nd=sum_nd/sum_nu
print, kk, avg_nd
endfor
====================결과값==========
0.100000 3.23064e-05
0.300000 0.000184444
0.500000 0.000434590
0.700000 -NaN
0.900000 -NaN
1.10000 0.00110647
1.30000 -NaN
1.50000 0.000382066
1.70000 0.000151461
1.90000 -NaN
2.10000 5.18493e-05
2.30000 2.86511e-05
2.50000 3.35374e-05
2.70000 1.53088e-05
2.90000 -NaN
3.10000 0.00000
3.30000 5.00900e-06
3.50000 0.00000
3.70000 0.00000
3.90000 -NaN
4.10000 0.00000
4.30000 0.00000
4.50000 0.00000
4.70000 0.00000
4.90000 0.00000
5.10000 0.00000
5.30000 0.00000
5.50000 0.00000
5.70000 0.00000
5.90000 0.00000
% Program caused arithmetic error: Floating illegal operand결과값이 다음과 같이 몇부분에서 NaN으로 뜨는데 이유를 모르겠어서 문의드립니다.
위에 코딩중 if (interval[ii] eq 0.7) then begin 이런식으로 제가 하나씩 주면 그 값이 제대로 나오는데.. for문으로 돌리면 0.7인부분에서 NAN 값으로 떠서
혹시 도움을 얻을 수 있을까해서 이렇게 글을 올립니다. -
Jonghyuk회원
1. 에러 메시지로 보았을 때, avg_nd=sum_nd/sum_nu 에서 sum_nd와 sum_nu 가 모두 초기치인 0.0 그대로여서 발생하는 문제로 추측됩니다.
IDL> print, 0.0/0.0
-NaN
% Program caused arithmetic error: Floating illegal operand2. if (interval[ii] eq 0.7) then begin
위와 같이 값을 지정하여 실행하시면 작동하는 것으로 보아 Floating Point 정밀도 문제인 것 같습니다.IDL> print, 0.7 eq 0.7 ;당연하지만
1
IDL> print, (0.1+(0.2*3))
0.700000
IDL> print, (0.1+(0.2*3))
0.700000
IDL> print, 0.7 eq (0.1+(0.2*3)) ;이 부분이 아마 문제의 핵심이 아닐까 생각합니다.
00.7과 0.7이 같은지 확인했는데 False(0) 이 나옵니다. 이유는 Float(Double도 마찬가지입니다)형 데이터의 정밀도에 한계가 있기 때문입니다(이는 현재 우리가 사용하는 모든 전산 장비가 가지는 한계입니다).
IDL> print, (0.1+(0.2*3)), format='(D20.15)’
0.700000047683716
IDL> print, 0.7, format='(D20.15)’
0.6999999880790710.7과 (0.1+(0.2*3)) 이 예상과 달리 ‘다른 값’ 이라는 것이죠.
이것이 IDL만의 문제가 아니어서, 이와 관련된 글들은 구글 검색으로 쉽게 찾아볼 수 있습니다.
일반적으로 이런 문제의 회피 방법은 유효 범위 이내에서 비교를 하는 것입니다. 다시 말해, 두 값이 같은지를 비교하는 것이 아니라, 두 값의 차이가 오차 범위 이내인지를 검사하는 것이죠.
IDL> print, abs(0.7 – (0.1+(0.2*3)))
5.96046e-008
IDL> print, abs(0.7 – (0.1+(0.2*3))) lt 0.001
1그래서,
if abs(interval[ii] – kk) lt 0.001 then begin
위와 같이 문제가 되는 부분을 수정해 보시면 어떨까 생각합니다. -
inmyta27회원
조언해주신대로 수정해 보았더니 값이 잘 산출됩니다.
너무 감사드려요~~
-
-
글쓴이글