3.1.5.3 실수 (Real Numbers): 수직선의 완성, 컴퓨터의 한계

학습목표

피타고라스를 공포로 몰아넣었던 무리수를 포용하여 진짜 수직선을 가득 채우는 실수의 개념을 잡습니다. 그리고 이 광활한 실수의 바다를 한정된 64비트 메모리에 담아내기 위한 파이썬의 부동 소수점(Floating Point) 전략과 오차의 필연성을 직시합니다.


1. 수직선의 빈틈을 메우다: 유리수와 무리수

정수(Integers)들 사이에는 수많은 공간이 텅 비어 있었습니다. 인류는 피자를 절반으로 공평하게 쪼개 먹기 위해 고안한 분수 형태의 유리수(Rational Numbers)로 이 거대한 간격을 촘촘히 채우기 시작했습니다. 하지만 이집트와 피타고라스 학파의 천재 기하학자들은 한 변이 $1$인 정사각형의 대각선 길이를 재다가 엄청난 수학적 모순에 직면합니다. 분수로는 도저히 나눠떨어지지 않는 무한한 숫자의 블랙홀, $\sqrt{2}$ 같은 무리수(Irrational Numbers)를 발견해 낸 것입니다.

무리수와 피타고라스 웹툰 (웹툰 비유: 딱딱 떨어지는 분수들(유리수)이 완벽하다 믿었던 피타고라스가, $1 \times 1$ 정사각형의 대각선(\sqrt{2})에서 쏟아져 나오는 끝없는 소수의 폭포(무리수)를 보고 공포에 질린 모습)

무리수는 끝없이 반복조차 되지 않는 영원한 소수점을 가집니다($\pi=3.14159265…$). 유리수와 이 다루기 힘든 무리수 두 세력이 결합하여 드디어 끊어짐 없이 완벽하게 연속된 1차원 수직선인 실수(Real Numbers) 세계관이 하나로 완성되었습니다.

  • 파이썬의 실수형 데이터 타입의 이름은 float 클래스입니다.
  • 3.14, -0.001, 2.0 등 소수점이 단 한 개라도 찍히는 숫자는 무조건 메모리에 정수(int)가 아닌 실수(float)로 배정됩니다.

2. 부동 소수점(Floating Point)의 딜레마

문제는 끝을 알 수 없는 무리수와 거대한 자리수의 소수점들을 어떻게 우리 눈앞의 유한한 컴퓨터 메모리에 집어넣느냐는 공학적 난제였습니다. 정수처럼 메모리에 그냥 담으려고 고정된 칸막이를 쳐버리면(고정 소수점 방식), 거대한 십진수나 끝없는 소수를 만날 때마다 엄청난 메모리 빈 공간이 낭비되거나 아예 담지 못해서 꼬리 부분이 날아가버립니다.

IEEE 754: 띄워놓고 잘라버리기 전략

파이썬 부동 소수점 오차 원리 한눈에 보기 (다이어그램: 64비트 크기의 파이썬 float 객체 내부 구조. $1/3$과 같이 무한 반복되는 소수를 부호(1bit), 지수부(11bits), 가수부(52bits)로 쪼개어 강제로 근사해 우겨넣다보니 미세 오차가 터지는 원리)

현대 컴퓨터는 부동 소수점(Floating Point) 기수법을 채택했습니다. 쉽게 말해 $250000$을 $2.5 \times 10^5$으로 표현하는 과학적 지수 표기법처럼, 고정된 자리를 쓰지 않고 소수점 자체를 물 위에 뜬 부표(Float)처럼 이리저리 둥둥 떠다니게 밀고 당겨서 한정된 64비트 메모리 조각에 거대한 숫자를 조약돌처럼 압축하는 방식입니다.

3. 부동 소수점 근사 오차 실습 (참값 vs 근삿값)

이 방법은 혁신적이었지만, 메모리 끝단에서 가장 뒤에 있는 찌끄러기 수들을 억지로 반올림하고 버려야(Truncate) 하는 근사치 저장 모형이라는 태생적 한계가 생겼습니다. 인간이 알아보기 편한 십진수 소수점을 컴퓨터가 2진수로 바꾸다가 필연적으로 발생하는 부동 소수점 오차는 모든 데이터/금융 개발자의 골머리를 썩입니다.

수학이야기 77. 근삿값과 오차 단원에서 배웠듯, 완벽한 이상 세계의 숫자인 참값(True Value)과 우리가 측정하거나 컴퓨터로 잘라서 흉내 낸 근삿값(Approximate Value) 사이에는 반드시 틈새비율인 상대 오차(Relative Error)가 발생합니다.

import math

perfect_real = 0.3    # 인간이 머리속으로 생각한 완벽한 참값
hacked_float = 0.1 + 0.2  # 컴퓨터가 2진수로 변환하다 잘려나간 근삿값의 합

print("1. 인간의 기대 (참값):", perfect_real)
print("2. 컴퓨터의 현실 (근삿값):", hacked_float)

# 두 값이 완벽히 일치하는지(==) 물어보면 컴퓨터는 거짓말을 못하기에 오차를 뱉습니다.
print("\n3. 두 값이 완벽히 똑같은가요? (==):", perfect_real == hacked_float)

출력 예측: False. 인간의 직관(0.3)과 달리, 끝부분 메모리가 허덕이며 쏟아낸 $0.000…04$ 의 쓰레기 값이 남아 수학적 참값과 어긋납니다.

수학적 타협: math.isclose() 의 위력

프로그래밍과 공학에서 “정확하다”는 것은 오차가 $0\%$임을 뜻하는 것이 아닙니다. 수학이야기에서 배웠듯 “우리가 합의한 상대 오차선 아래로 들어왔다면 같다고 친다!” 라는 타협의 기술입니다. 파이썬은 이를 위해 math.isclose() 함수를 제공합니다.

# "참값 대비 상대 오차가 0.0000001% (1e-09) 이하로 미세하게 나면 같은 숫자로 인정해 줄게!"
if math.isclose(hacked_float, perfect_real, rel_tol=1e-09):
    print("-> 팩트: 둘의 허용 오차 한계를 통과하여 '같은 값'으로 수학적 타협을 봅니다!")
else:
    print("-> 팩트: 오차가 너무 커서 다른 숫자로 판정!")

🛡️ 방어 코딩(Vibe Coding): 실제 은행권의 통화 소수점 단위 계산이나, NASA 같이 로켓 우주 공학 궤도 연산 시뮬레이션에서는 이 미세한 오차가 폭발을 부릅니다. 이에 float 대신 오차가 없는 외부 과학 모듈인 decimal이나 분수 모듈 fractions를 특별히 불러와 사용해야만 합니다.


4. 정수와 실수 사이의 차원 이동 (Type Casting)

정수(int)는 블록처럼 딱딱 끊어지는 이산적인 점이고, 실수(float)는 소수점으로 꿀처럼 이어지는 연속적인 1차원 선입니다. 파이썬은 이 서로 다른 두 생태계를 넘나들 수 있는 강력한 마법 지팡이(형변환 함수)들을 제공합니다.

정수와 실수 형변환 변환 원리 애니메이션 (다이어그램: float() 함수를 쓰면 정수에 .0 날개가 달려 1차원 실수로 승격되지만, 반대로 int() 함수를 쓰면 소수점 자리가 무참히 잘려(Truncate) 나가는 데이터 손실 패널티를 시각화)

  1. float() 함수 (승격): 정수를 밀어넣으면 즉시 소수점 .0이 붙고 연속된 실수 모델(64비트 근사 모델)로 차원이 승격됩니다.
  2. int() 함수 (강등과 손실): 반대로 찰랑거리는 실수 데이터를 정수 상자에 밀어넣으면 어떻게 될까요? 파이썬의 int()는 반올림 따위를 해주지 않습니다. 소수점 아래 꼬리를 가위로 무참히 잘라 버리는 버림(Truncate) 연산을 통해 정수 부분만 추출합니다.
gravity = 9.81
count = 5

print("--- [ 실수 <-> 정수 형변환 마법 ] ---")

# 1. 정수를 실수로 승격 
# 데이터 손실이 전혀 없이 뒷자리에 .0이 붙어 정확도 유지
cast_float = float(count)
print(f"float({count}) -> {cast_float} (타입: {type(cast_float)})")

# 2. 실수를 정수로 강등 (무자비한 절사 발생!)
# 반올림이 아니라 소수점이 '잘려 나가는' 치명적 데이터 손실에 주의!
cast_int = int(gravity)
print(f"int({gravity}) -> {cast_int} (타입: {type(cast_int)})")

예측 출력 결과:

--- [ 실수 <-> 정수 형변환 마법 ] ---
float(5) -> 5.0 (타입: <class 'float'>)
int(9.81) -> 9 (타입: <class 'int'>)

4. 코딩 영단어 학습 📝

  • Float: 둥둥 떠다니다. 바다 위 찌와 부표 모양처럼, 소수점 위치를 고정하지 않고 메모리 효율을 위해 앞뒤로 둥둥 떠다니며(Floating Point) 숫자를 저장하고 근사시키는 파이썬의 핵심 ‘실수’ 자료구조입니다.
  • Rational: 수학이야기(#84) 유리수 편에서, 두 정수의 ‘비율(Ratio)’인 분수로 나타낼 수 있는 깔끔한 숫자들(이성적인, 합리적인)을 뜻합니다.
  • Irrational: 비율로 나타낼 수 없는, 무한하고 반복성조차 안갯속인 숫자의 블랙홀(무리수, 비이성적인). 컴퓨터의 float 한계를 불러온 주범입니다.
서브목차