파이썬은 부동소수점형식을 쓰고 있어, 아래와 같은 문제가 나타남.
문제
두 실수를 비교했지만 같지 않다고 나옴.
0.1 + 0.2 == 0.3 # false
0.1 + 0.2 # 0.30000000000000004
해결책
파이썬은 실수를 부동소수점 방식으로 표현하고 있으며, 부동소수점은 실수를 정확하게 표현할 수 없는 문제가 있다. 부동소수점으로 실수를 표현하면, 소숫점 이하가 무한히 반복되기 때문에 일정 시점에 반올림하여 근사값을 구한다. 실제 값과 근사값에서 발생하는 오차를 부동소수점 반올림 오차(rounding error) 라고 부른다. 이 오차는 항상 머신 엡실론(machine epsilon / sys.float_info.epsilon에 저장된 값/ 반올림 오차의 상한 값)보다 작다. 따라서 실수를 비교할 때는 연산한 값과 비교값의 차이를 구한 뒤 머신 엡실론보다 작거나 같은지 판단해야 한다. 작거나 같다면 두 실수는 값은 값이라 판단할 수 있다.
방법1.
1. math, sys함수는 내장함수가 아니라서 import 명령어를 사용해 모듈을 불러옴.
2. math.fabs()를 이용하여 두값의 차이를 절대값으로 만들면 음수값이 나오더라도 정상적으로 판단 가능.
3. 그렇게 해서 나온 절대값과 머신 엡실론과 작거나 같은지를 비교
import math, sys
x = 0.1 + 0.2
math.fabs(x - 0.3) # <= sys.float_info.epsilon
>>> True
방법 2.
위와 같은 기능을 하는 math.isclose()함수를 이용하여 판단.
import math
math.isclose(0.1 + 0.2, 0.3)
>>>True
방법 3.
round함수(반올림)를 이용해 소수점 특정자리까지 비교.
round(0.1+0.2, 1) == round(0.3, 1) #round(값, 표현할 자릿수)
>>> True
방법 4.
숫자를 10진수로 처리하여 정확한 소수점 자릿수를 표현하는 decimal 모듈의 Decimal을 사용.
from decimal import Decimal
Decimal('0.1') + Decimal('0.2') == Decimal('0.3')
>>> True