파이썬은 정확한 십진수 부동소수점 연산을 위해 decimal 모듈을 제공합니다. 이 모듈에는 소수점 계산을 효율적으로 처리할 수 있도록 도와주는 수많은 함수가 내장되어 있습니다. 이번 글에서는 그중에서도 가장 널리 사용되는 핵심 함수들을 예제 코드와 함께 자세히 살펴보겠습니다.
1. compare() – 두 Decimal 값 비교하기
compare() 함수는 두 개의 십진수를 비교하는 데 사용됩니다. 첫 번째 값이 두 번째 값보다 크면 1, 작으면 -1, 같으면 0을 반환합니다.
예제
import decimal
val1 = decimal.Decimal(2.6)
val2 = decimal.Decimal(2.61)
# 십진수 비교
print("결과 : ", val1.compare(val2))
# 값 재설정
val1 = decimal.Decimal(2.6)
val2 = decimal.Decimal(-2.6)
# 십진수 비교
print("결과 : ", val1.compare(val2))
# 값 재설정
val1 = decimal.Decimal(2.6)
val2 = decimal.Decimal(2.6)
# 십진수 비교
print("결과 : ", val1.compare(val2))
출력 결과
결과 : -1 결과 : 1 결과 : 0
2. max()와 min() – 최댓값과 최솟값 구하기
max()와 min() 함수는 각각 두 개의 십진수 중 최댓값과 최솟값을 찾아줍니다.
예제
import decimal
val1 = decimal.Decimal(2.6)
val2 = decimal.Decimal(2.61)
print("최댓값 : ", round(val1.max(val2), 2))
print("최솟값 : ", round(val1.min(val2), 2))
출력 결과
최댓값 : 2.61 최솟값 : 2.60
3. getcontext() – 연산 정밀도 조절하기
getcontext() 메서드를 사용하면 산술 연산의 정밀도(precision)를 직접 변경할 수 있습니다. 기본 정밀도는 28자리입니다. 아래 예제에서는 getcontext().prec로 설정한 정밀도에 따라 연산 결과가 어떻게 달라지는지 확인할 수 있습니다.
예제
from decimal import * print(Decimal(13) / Decimal(7)) getcontext().prec = 6 print(Decimal(13) / Decimal(7)) getcontext().prec = 10 print(Decimal(13) / Decimal(7))
출력 결과
1.857142857142857142857142857 1.85714 1.857142857
기본 상태에서는 28자리까지 출력되지만, 정밀도를 6으로 설정하면 소수점 이하 5자리까지만, 10으로 설정하면 소수점 이하 9자리까지 표시됩니다.
4. exp() – 지수 함수(e^x) 계산하기
exp() 함수는 주어진 숫자에 대한 자연지수 함수 ex의 값을 반환합니다.
예제
from decimal import * # e 값 구하기 print(Decimal(1).exp()) # e의 2제곱 구하기 print(Decimal(2).exp()) # e의 4제곱 구하기 print(Decimal(4).exp())
출력 결과
2.718281828459045235360287471 7.389056098930650227230427461 54.59815003314423907811026120
5. as_integer_ratio() – 분수 형태의 정수 쌍 얻기
때로는 해당 십진수를 만들 수 있는 두 정수(분자와 분모)가 필요할 때가 있습니다. 이럴 때 as_integer_ratio()를 사용하면 손쉽게 정수 쌍을 얻을 수 있습니다.
예제
from decimal import *
v = Decimal('2.1834').as_integer_ratio()
print(v)
v = Decimal('-1.92').as_integer_ratio()
print(v)
출력 결과
(10917, 5000) (-48, 25)
즉, 2.1834는 10917/5000으로, -1.92는 -48/25로 표현할 수 있습니다.
6. ln()과 log10() – 로그 계산하기
ln() 함수는 자연로그(밑이 e인 로그)를, log10() 함수는 밑이 10인 상용로그를 계산합니다. 로그를 구하고자 하는 십진수 값을 인자로 전달하면 됩니다.
예제
from decimal import *
ln_val = Decimal('2.1').ln()
print(ln_val)
log_val = Decimal('2.1').log10()
print(log_val)
출력 결과
0.7419373447293773124826065257 0.3222192947339192680072441618
7. fma(a, b) – 융합 곱셈-덧셈(Fused Multiply-Add)
fma()는 'Fused Multiply and Add'라고 불리는 특수한 함수입니다. 호출한 십진수 값에 첫 번째 인자 a를 곱한 뒤, 그 결과에 두 번째 인자 b를 더합니다. 즉, 한 번의 연산으로 곱셈과 덧셈을 동시에 처리하여 반올림 오차를 줄일 수 있습니다.
예제
from decimal import * # (2.1 * 2) + 5와 동일 fma_val = Decimal(2.1).fma(2, 5) print(fma_val) # (8.1 * 3) + 5와 동일 fma_val = Decimal(8.1).fma(3, 5) print(fma_val)
출력 결과
9.200000000000000177635683940 29.29999999999999893418589636
참고로 위 예제에서 Decimal(2.1)처럼 부동소수점 리터럴을 그대로 전달하면 이진 부동소수점 표현의 한계로 인해 미세한 오차가 포함될 수 있습니다. 완전히 정확한 결과가 필요하다면 Decimal('2.1')처럼 문자열로 전달하는 것이 좋습니다.
마무리
파이썬의 decimal 모듈은 금융 계산, 과학 연산 등 높은 정확도가 요구되는 십진수 처리에 필수적인 도구입니다. 비교(compare, max/min), 정밀도 제어(getcontext), 수학 함수(exp, ln, log10, fma), 분수 변환(as_integer_ratio) 등 다양한 기능을 활용하면 부동소수점 오차 없이 신뢰할 수 있는 연산 결과를 얻을 수 있습니다.