08. 여덟 번째 수업: 컴퓨터와 유리수 (Rationals in Computers)
지금까지 우리는 유리수가 분자와 분모의 완벽한 비율($\frac{a}{b}$)로 존재한다는 것을 배웠습니다. 그런데 우주선의 궤도를 시뮬레이션하거나 금융 데이터를 다루는 실제 프로그래머들은 유리수를 어떻게 컴퓨터 메모리에 저장할까요? 안타깝게도 우리의 일반적인 기대와 컴퓨터의 현실에는 아주 큰 제약이 존재합니다.
1. 부동소수점 (Floating Point)의 배신
대부분의 프로그래밍 언어(파이썬 포함)는 소수점 계산을 할 때 부동소수점(float) 이라는 방식을 씁니다.
이 방식은 실생활의 측량에서는 굉장히 빠르고 편리하지만, 치명적인 약점이 있습니다. 컴퓨터는 데이터를 0과 1의 ‘이진수(Binary)’로만 이해할 수 있기 때문에, $10$진수의 평범한 소수를 컴퓨터의 2진수로 바꾸는 과정에서 할당된 메모리 공간(64비트)을 넘어서는 무한소수들을 끝에서 강제로 싹둑 자르고 반올림해버립니다.
즉, 완벽해야 할 비율의 세계에 미세한 오차(Error)가 발생하게 됩니다.
예를 들어, 우리가 계산기에 $0.1 + 0.2$를 치면 당연히 $0.3$이 나올 것이라고 확신합니다. 하지만 파이썬에게 이 계산을 시켜보면 충격적인 결과를 보게 됩니다.
# [Python] 0.1 + 0.2 는 정말로 0.3 이 맞을까?
a = 0.1
b = 0.2
result = a + b
print(f"0.1 + 0.2 = {result}")
if result == 0.3:
print("계산이 완벽히 일치합니다!")
else:
print("충격! 컴퓨터의 Float 한계로 인해 값이 일치하지 않습니다!")
[실행 결과]
0.1 + 0.2 = 0.30000000000000004
충격! 컴퓨터의 Float 한계로 인해 값이 일치하지 않습니다!
컴퓨터 메모리의 $64$비트 우편함으로는 무한의 세계를 완벽히 담아낼 수 없어서, 끝자리에 미세한 쓰레기값(0.000...04)이 달라붙었기 때문입니다. 이 오차를 무시하고 은행 우주선을 쏘아 올린다면 궤도가 틀어져 화성이 아닌 목성으로 날아가 버릴 것입니다!
2. 구원자: fractions 모듈 (완벽한 비율계산기)
이러한 부동소수점의 치명적인 오차를 막기 위해, 정말로 정밀한 수학/과학 계산이 필요한 프로그래머들은 소수(Float)를 쓰지 않습니다. 대신 유리수의 원형 형태(분자/분모)를 메모리에 고스란히 저장하는 특별한 도구를 씁니다.
파이썬에서는 fractions.Fraction이라는 마법사가 그 역할을 합니다.
# [Python] 오차율 0% 의 절대 계산: 분수(Fraction) 모듈
from fractions import Fraction
# 소수점(0.1, 0.2)을 쓰지 않고 가장 순수한 분수 형태로 변수를 만들겠습니다.
a = Fraction(1, 10) # 1/10 (0.1)
b = Fraction(2, 10) # 2/10 (0.2)
target = Fraction(3, 10) # 3/10 (0.3)
result = a + b
print(f"{a} + {b} = {result}")
if result == target:
print("축하합니다! 오차율 0%로 완벽하게 3/10 과 일치합니다!")
else:
print("계산 실패...")
[실행 결과]
1/10 + 1/5 = 3/10
축하합니다! 오차율 0%로 완벽하게 3/10 과 일치합니다!
(파이썬은 내부적으로 2/10을 가장 가벼운 기약분수인 1/5로 알아서 스위칭하여 계산해주었습니다.)
소수점 오류 없이 계산을 통분하여 3/10이라는 완벽한 유리수로 결과를 반환했습니다.
마무리
유리수는 “정수와 정수의 완벽한 비율”이라는 아름다운 개념에서 출발했지만, 현실 세계(컴퓨터)에서는 메모리의 한계 때문에 Float 자료형이 어쩔 수 없이 무한을 유한으로 깎아내며 오차를 만듭니다. 우리는 수학적 이상($a/b$ 비율)과 컴퓨터 공학적 현실(메모리 바이트 한계)의 차이를 이해하고, 상황에 맞는 가장 완벽한 코드를 짜야만 합니다.
다음 장부터는 이 유리수의 한계마저도 훌쩍 뛰어넘는, 수직선의 텅 빈 공간을 가득 메우는 촘촘한 수인 “실수(Real Numbers)”와 억울하게 바다에 빠져 죽은 사나이, 히파소스의 이야기를 다루어보겠습니다!