06. 여섯 번째 수업: 파이썬 정밀도 시뮬레이터 (Precision in Python)
현실의 모든 측정 시스템(눈금선, 각도기, 저울)과 컴퓨터의 모든 부동소수점(float) 램 메모리는 어쩔 수 없는 ‘오차의 한계’를 지니고 태어났습니다.
하지만 우리가 은행 시스템을 만들거나 자율주행 차의 미사일 궤도를 수정할 때는 이 미세한 오차가 나비효과가 되어 치명적인 결함으로 번질 수 있습니다. 오차 단원의 마지막 수업으로, 파이썬이 이 불완전한 근삿값들을 통제하기 위해 제공하는 두 가지 강력한 방어막을 세팅해 봅시다!
1. 정밀 포격 통제소: decimal 모듈
0.1 + 0.2 가 0.30000000000004 로 박살 나는 64비트의 저주(부동 소수점 에러)를 피하려면 파이썬 기본 float의 스위치를 내리고 인간의 돈(10진수) 계산에 특화된 객체를 사용해야 합니다.
- 이 도구를 사용하면 “측정값”의 소수점 정밀도를 내 마음대로 무한 확장할 수 있습니다.
- 유효숫자 $15$자리가 한계인 CPU 칩 대신, 램 메모리를 왕창 사용하여 유효숫자 $100$자리, $1000$자리를 유지하는 괴물이 됩니다.
# [Python] 64비트의 오차를 박살내는 초정밀 객체 Decimal
from decimal import Decimal, getcontext
print("--- [일반 무기 (Float)] ---")
normal_a = 0.1
normal_b = 0.2
print(f"0.1 + 0.2 = {normal_a + normal_b} (오차 발생!)")
print("\n--- [비밀 무기 (Decimal)] ---")
# 문자열('0.1') 로 객체를 초기화 해야 중간 변환 오차가 개입하지 못합니다.
dec_a = Decimal('0.1')
dec_b = Decimal('0.2')
print(f"0.1 + 0.2 = {dec_a + dec_b} (완벽한 인간계 덧셈 성공!)")
# 유효숫자 정밀도를 미친듯이 끌어올리기 (기본 28자리 -> 50자리로 세팅)
getcontext().prec = 50
print("\n[초정밀도 50자리로 나누기 7을 시전합니다]")
print(Decimal('1') / Decimal('7')) # 0.14285714285714285714285714285714285714285714285714
2. 오차 허용의 미학: math.isclose() (상대 오차)
과학자들은 “100% 똑같은 숫자”라는 기적을 믿지 않습니다. 그저 “내가 허용한 에러율(상대 오차율) 안으로 두 측정값이 들어왔는가?” 라는 그물을 칩니다.
앞서 짧게 소개했던 isclose() 함수는 사실 이 그물의 촘촘함(허용 오차 한계선)을 조율하는 마스터 키업니다.
rel_tol: 상대 오차(Relative Tolerance). 전체 크기 대비 허용선 (예: 1억 원 중 1원 틀리는 건 봐줌)abs_tol: 절대 오차(Absolute Tolerance). 크기와 상관없이 절대적으로 허용 가능한 최솟값 거리 (예: 죽어도 $\pm 0.001$ 안에 들어와야 함). 보통 온도를 잴 때 강력합니다.
# [Python] 측정값 사이트의 허용 오차 그물망 넓히기
import math
# 목수 A와 B가 길이를 쟀습니다.
measurement_A = 100.000
measurement_B = 100.005 # 0.005 의 오차!
print("[오차 재판소: 둘은 같은 규격의 파이프인가?]")
# 1. 일반 비교 (거부됨!)
if measurement_A == measurement_B:
pass
else:
print("1. == 절대 비교: 불합격! (둘은 완전히 다른 길이입니다)")
# 2. 아주 타이트한 그물망 (상대오차 0.001% 만 허용 = 1e-05)
if math.isclose(measurement_A, measurement_B, rel_tol=1e-05):
print("2. 초정밀 타이트 비교: 합격! 같다고 칩니다.")
else:
print("2. 초정밀 타이트 비교: 불합격! (너무 엄격해서 0.005를 용서하지 않음)")
# 3. 넉넉한 그물망 (상대오차 0.1% 허용 = 1e-03)
if math.isclose(measurement_A, measurement_B, rel_tol=1e-03):
print("3. 넉넉한 0.1% 통과: 합격! (이 정도 오차는 눈감아 주고 같은 부품으로 씁니다)")
[실행 결과]
[오차 재판소: 둘은 같은 규격의 파이프인가?]
1. == 절대 비교: 불합격! (둘은 완전히 다른 길이입니다)
2. 초정밀 타이트 비교: 불합격! (너무 엄격해서 0.005를 용서하지 않음)
3. 넉넉한 0.1% 통과: 합격! (이 정도 오차는 눈감아 주고 같은 부품으로 씁니다)
시스템 종료
현실의 불규칙한 원자 세계와 플라스틱 자눈금의 파동 속에서 살아가는 우리는, 절대적인 $100\%$ 진리에 도달할 수 없습니다. 인간을 겸손하게 만들고 타협을 허락하는 이 ‘오차(Error)’와 ‘근삿값(Approximation)’의 위대한 메커니즘을 제대로 숙지하고 파이썬으로 방어벽을 세운다면, 여러분은 우주 미사일이 폭발하는 참사를 막을 수 있는 진정한 공학자로 거듭나게 될 것입니다.
서브목차