[Python] float, Decimal, Fraction
python float, python decimal, python fraction, 부동소수점, 정밀 산술
정의
Python의 실수 산술은 세 가지 타입을 제공한다.
float: IEEE 754 double precision (64비트). Cdouble과 동일. 빠르지만 부정확.decimal.Decimal: 임의 정밀도 십진수. 금융·통화 계산용. 느리지만 정확.fractions.Fraction: 분수 표현. 유리수 정확 계산. 가장 느림.
float: IEEE 754 double
python
x = 0.1 + 0.2
print(x)
print(x == 0.3)
print(repr(x)) # 모든 비트 표시 결과
0.30000000000000004
False
0.300000000000000040.1과 0.2는 2진 부동소수로 정확히 표현되지 않는다. 누적 오차가 발생한다.
부동소수 비교
직접 == 대신 math.isclose()를 써라.
python
import math
print(math.isclose(0.1 + 0.2, 0.3)) # True
print(math.isclose(0.1 + 0.2, 0.3, abs_tol=1e-9)) 결과
True
True특수 값
import math
math.inf # 양의 무한대
-math.inf # 음의 무한대
math.nan # Not a Number
float("inf")
float("-inf")
float("nan")
math.isnan(math.nan) # True
math.isinf(math.inf) # True
# NaN은 자기 자신과도 != 다.
math.nan == math.nan # False
float 정보
import sys
sys.float_info
# epsilon=2.22e-16, mant_dig=53, max=1.79e+308, min=2.22e-308
Decimal: 정확한 십진 산술
python
from decimal import Decimal, getcontext
a = Decimal("0.1") + Decimal("0.2")
print(a)
print(a == Decimal("0.3"))
# 정밀도 설정
getcontext().prec = 50
print(Decimal(1) / Decimal(7)) 결과
0.3
True
0.142857142857142857142857142857142857142857142857143중요: Decimal(0.1)은 float를 통하므로 부정확. 반드시 문자열로 생성 Decimal("0.1").
python
from decimal import Decimal
print(Decimal(0.1)) # float에서 변환 (부정확)
print(Decimal("0.1")) # 문자열에서 (정확) 결과
0.1000000000000000055511151231257827021181583404541015625
0.1금융 계산 예시
from decimal import Decimal, ROUND_HALF_UP
price = Decimal("19.99")
tax_rate = Decimal("0.13")
tax = (price * tax_rate).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
total = price + tax
# Decimal('22.59')
Fraction: 유리수 정확 계산
python
from fractions import Fraction
a = Fraction(1, 3)
b = Fraction(1, 6)
print(a + b)
print(a * 6)
# float에서 생성 (주의: 부정확한 분수)
print(Fraction(0.1))
print(Fraction("0.1")) 결과
1/2
2
3602879701896397/36028797018963968
1/10Fraction(0.1)은 float의 실제 비트 표현을 분수로 옮긴 결과다. 문자열 입력이 안전하다.
언제 무엇을 쓰나
| 상황 | 선택 |
|---|---|
| 과학 계산, ML, 통계 | float (NumPy 권장) |
| 금융, 통화, 회계 | Decimal |
| 기호 수학, 유리수 정확 비교 | Fraction |
| 빠른 정수 산술 | int (임의 정밀도) |
변환
int(3.7) # 3 (소수 버림)
float("3.14") # 3.14
float("inf") # inf
Decimal("1.5")
Fraction("3/7")
round(3.14159, 2) # 3.14
round(2.5) # 2 (bankers' rounding: 짝수로)
round(3.5) # 4
round()는 bankers’ rounding(반올림이 정확히 0.5일 때 짝수로)을 쓴다. 일반적인 사사오입은 decimal.Decimal.quantize(..., ROUND_HALF_UP).
💬 댓글