08. 여덟 번째 수업: 컴퓨터 속의 실수 (Computing Reals)

유리수와 무리수를 아우르는 거대한 대륙 ‘실수’의 세계를 모두 여행했습니다. 하지만 앞선 유리수 단원에서도 언급했듯, 무한의 바다를 컴퓨터의 비좁은 메모리 섬에 억지로 처넣을 때는 반드시 누수가 발생합니다.


1. IEEE 754: 세상을 지배하는 64비트 실수 표준 규약

여러분의 스마트폰 틱톡 앱부터 로켓 시뮬레이터까지, 전 세계 모든 컴퓨터가 실수를 표현할 때는 IEEE 754 부동소수점(Floating Point)이라는 강력한 국제 룰을 사용합니다.

컴퓨터 메모리는 무한하게 뻗어가는 무리수(예: $1.414213…$)나 심지어 유리수인 $0.1$ 조차 소수점이 길어지면 뒤쪽 숫자를 버리고, 오직 64비트(0과 1의 칸 64개) 안에 강건하게 구겨 넣습니다.

  • 부호(Sign): $1$ 비트
  • 지수(Exponent): $11$ 비트 (소수점의 위치를 왼쪽 오른쪽으로 얼마나 밀 것인가?)
  • 가수(Fraction) : $52$ 비트 (실제 숫자의 유효 정밀도. $15 \sim 17$ 자리 수준)

실수(Real)는 수학의 신이 만든 연속적 개념이지만, 컴퓨터 속의 실수는 현미경으로 확대해 보면 유리수처럼 $0.000…1$ 단위로 이빨이 듬성듬성 나 있는 ‘유한 집합’일 뿐입니다.

2. 파이썬 decimal 에도 한계는 있다

파이썬의 float 오차를 막기 위해 초정밀 소수 계산 엔진인 decimal 모듈을 자주 씁니다. 그렇다면 이 decimal은 진짜 무한의 무리수를 완벽히 담지할 수 있을까요?

# [Python] 아무리 정밀한 Decimal 이라도, 결국엔 낭떠러지(Precision Limit)가 있다!
import decimal
from decimal import Decimal

print("초정밀도 Decimal 모듈로 루트 2 의 소수점 우주를 개방합니다.\n")

# 기본 정밀도는 28 자리입니다. (float 의 15자리를 훨씬 뛰어넘음)
ctx = decimal.getcontext()
ctx.prec = 28
print(f"1. [정밀도 28자리] 루트 2: {Decimal(2).sqrt()}")

# 정밀도를 200자리 괴물급으로 늘려봅니다.
ctx.prec = 200
print(f"\n2. [정밀도 200자리] 루트 2: {Decimal(2).sqrt()}")

print("\n-> 컴퓨터의 RAM 용량만 허락한다면 정밀도를 100만 자리까지도 늘릴 수 있습니다.")
print("-> 하지만 영원히 숫자를 반환하지 못합니다. '계산'하다 메모리가 터져버릴 뿐!")

아무리 decimal 객체에 램 할당을 무지막지하게 해줘서 수십만 자리의 소수를 보여주더라도, 영원한 무리수의 본질을 끝맺는 것은 불가능합니다. 그저 소수점 낭떠러지를 더 멀리 밀어냈을 뿐입니다.

마무리

유리수에서 한계를 느끼고 바다 밖으로 나아간 히파소스의 발견 덕분에 무리수가 등장했고, 그 파편들이 수직선의 모든 빈틈을 메워 실수의 위대한 세계관이 완성되었습니다.

그러나 아무리 완벽해 보이는 이 실수의 수직선조차, 곧 배울 다음 단원에서는 어떤 방정식($x^2 = -1$)을 만나며 산산이 부서지게 됩니다. 수직선을 벗어나 완전한 상상력의 2차원 공간으로 날아가는 궁극의 숫자, 복소수(Complex Numbers)가 여러분을 기다리고 있습니다!

서브목차