sclee10
가입: 2018년 9월 13일 올린 글: 2
|
올려짐: 2018년9월16일 20:52 주제: 2-1 floating point 오차는 INTEGRAL 범위 오차에 의한 계산 결과 오차까지 인정되나요? |
|
|
구현에 따라 발생할 수 있는 floating point 오차는 용인해주시겠다고 하셨습니다.
계산 값의 오차만을 말씀하시는건지, 적분범위 계산에서 발생하는 부동소수점 오차에 의해서 생기는 결과의 오차까지 포함하시는건지 궁금합니다.
구체적으로는
올려주신 테스트 케이스에서
calculate(INTEGRAL(REAL 1.0, REAL (-5.0), X))
= -calculate(INTEGRAL(REAL (-5.0), REAL 1.0, X))
= -(-5.0 + -4.9 + -4.8 + ... + 0.7 + 0.8 + 0.9)
이렇게 계산하게 될 텐데, 여기서 -5.0 + -4.9 + -4.8 + ... + 0.7 + 0.8 + 0.9 수열을 두가지 방식으로 구현할 수 있습니다.
range_accum a b =
a
a +. 0.1
a +. 0.1 +. 0.1
a +. 0.1 +. 0.1 +. 0.1
...
a +. ... +. 0.1 ( <= b - 0.1 )
range_offset a b =
a +. 0.1 *. (float 0)
a +. 0.1 *. (float 1)
a +. 0.1 *. (float 2)
a +. 0.1 *. (float 3)
...
a +. 0.1 *. (float n) ( <= b - 0.1 )
이런상황에서 둘은 이런 차이를 보입니다.
rangef_accum (-5.0) 1.0 =
[-5.; -4.9; -4.80000000000000071; ...; 0.799999999999998934; 0.899999999999998912]
rangef_offset (-5.0) 1.0 =
[-5.; -4.9; -4.8; ... ; 0.700000000000000178; 0.800000000000000711]
rangef_offset은 -5. +. 0.1 *. 59. = 0.900000000000000355 > 0.9 라서 오차가 더 적지만 0.9에 해당하는 값이 포함되지 않았고
rangef_accum은 -5. +. 0.1 +. 0.1 +. ... +. 0.1 = 0.899999999999998912 <= 0.9 라서 오차가 더 크지만 0.9에 해당하는 값이 포함되게 됩니다.
이렇게 돼서 결국 rangef_accum을 사용하면 12.3, rangef_offset을 사용하면 12.39 라는 다른 결과를 내게 됩니다.
또 두가지 버전 모두가 공통적으로 포함하는 문제인데
rangef 1.0 1.1 = [1.] 인데 ( 1.0 +. 0.1 = 1.1 <= 1.1)
rangef 1.1 1.2 = [] 이 됩니다. (1.1 +. 0.1 = 1.20000000000000018 > 1.2 )
이런 경우도 감안해주시는건가ㅏ요? |
|