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타입을 사용했을 때와 동일한 문제가 발생한다.
'파이썬 문법' 카테고리의 다른 글
파이썬 우선순위 큐 (Priority Queues) (1) | 2024.02.29 |
---|---|
파이썬 enumerate (0) | 2024.02.27 |
파이썬 리스트 합치기 (2) | 2024.02.24 |
파이썬 내장 모듈 Collections (0) | 2023.11.20 |
파이썬- 문자열 관련 문법(포매팅, strip, split, join) (0) | 2022.07.05 |