어떤 프로그램 언어를 쓰든 0.1 + 0.2 ≠ 0.3 이 되는 것이 당연(?)합니다.

또한 1.0/(0.1 + 0.2 - 0.3)   ∞ 이 되는 것도 당연(?)합니다.

>>> 0.1 + 0.2 - 0.3
5.551115123125783e-17
>>> 0.1 + 0.2 - 0.3 > 1.0E-17
True
>>> 0.1 + 0.2 - 0.3 > 1.0/10E17
True

0.1 + 0.2 - 0.3 이 1.0E-17 즉 0.000000000000000001 보다 크다고 합니다.

 

이래 가지고서는 부동소수점수의 계산 결과를 어디 까지 믿을 수

있는지 의문입니다.

(보통으로는 배정밀도 부동소수점수는 유효수자 개수가 14개~15개 정도입니다.)

 

다행히 Python 의 fractions 모듈과 decimal 모듈을 사용하면

이런 오류를 쉽게 복구할 수 있습니다.

아래는 Python 3 인터프리터로 실행한 결과입니다.

(fractions.Fraction 객체).limit_denominator() 가 문제 해결의 핵심입니다.

(조금 번거럽네요.)

 

>>> import fractions, decimal, math
>>> a = fractions.Fraction(0.1)
>>> b = fractions.Fraction(0.2)
>>> c = fractions.Fraction(0.3)
>>> a + b == c
False
>>> 0.1 + 0.2 == 0.3
False
>>> a + b > c
True
>>> 0.1 + 0.2 > 0.3
True
>>> a + b - c
Fraction(1, 36028797018963968)
>>> 0.1 + 0.2 - 0.3
5.551115123125783e-17
>>> a2 = a.limit_denominator()
>>> b2 = b.limit_denominator()
>>> c2 = c.limit_denominator()
>>> a2, b2, c2
(Fraction(1, 10), Fraction(1, 5), Fraction(3, 10))
>>> a, b, c
(Fraction(3602879701896397, 36028797018963968), Fraction(3602879701896397, 18014398509481984), Fraction(5404319552844595, 18014398509481984))
>>> a2 + b2
Fraction(3, 10)
>>> "%s" % (a2 + b2)
'3/10'
>>> print("%s" % (a2 + b2))
3/10
>>> c2
Fraction(3, 10)
>>> "%s" % (c2)
'3/10'
>>> print("%s" % (c2))
3/10
>>> a2 + b2 == c2
True
>>> a2 + b2 - c2
Fraction(0, 1)
>>> print(a2 + b2 - c2)
0
>>> print("%s" % (a2 + b2 - c2))
0
>>> print("%d" % (a2 + b2 - c2))
0
>>> print("%d" % (a2 + b2))
0
>>> print("%d" % (c2))
0

 

 

Posted by Scripter
,