파이썬 문법

파이썬의 소수 연산 - float 타입과 decimal 모듈

토리쟁이 2022. 10. 7. 20:11

 

1. float 타입

파이썬은 다른 언어들처럼 float타입의 소수를 내부적으로 이진수의 형태로 저장한다.

ex) 0.875 ==> 0.111 (1/2 + 1/4 + 1/8)

하지만, 모든 10진 소수가 위와 같이 딱 떨어지게 이진 소수의 형태로 표현되지는 않는다.

ex) 0.895 ==> 0.111001010001111011... 처럼 무한 소수가 되기도 한다.

 

즉, 컴퓨터는 10진 소수를 2진 소수의 형태로 변환하여 저장하는데,

모든 10진 소수를 완전한 2진 소수로 나타낼 수 없다는 한계가 존재한다.

 

파이썬의 float 연산은 10진수 기반이 아닌 2진수 기반의 연산이므로 소수 연산을 할 때 우리의 생각과 다른 답이 도출될 수 있다.

>>> 1.1 + 2.2
3.3000000000000003
>>> 0.1 * 3 == 0.3
False
>>> 1.2 - 0.1 == 1.1
False
>>> 0.1 * 0.1 == 0.01
False

이러한 미세한 연산의 오류는 한치의 오차도 용납되지 않는 금융권 시스템에서 치명적인 버그로 이어질 수 있다.

 

2. decimal 모듈

1번에서 다룬 파이썬의 float연산에 대한 오류를 방지하기 위해 10진수 기반의 연산을 제공하는 파이썬의 내장함수인 decimal 모듈을 사용할 수 있다.

decimal 내장 모듈의 Decimal 클래스를 사용해서 위에서 했던 연산을 다시 해보자.

>>> from decimal import Decimal
>>> Decimal('1.1') + Decimal('2.2')
3.3
>>> import decimal
>>> decimal.Decimal('0.1') * 3 == decimal.Decimal('0.3')
True
>>> decimal.Decimal('0.3') + 2
Decimal('2.3')

10진수 기반의 연산이 된 것을 알 수 있다.

 

주의할 점은 Decimal() 안에 숫자가 아닌 문자열의 형태로 넘겨야된다는 점이다.

문자열 대신 숫자를 넘길 경우, float타입을 사용했을 때와 동일한 문제가 발생한다.