3.1.5.2 정수 (Integers): 제로섬과 오버플로우의 극복
학습목표
물리적 개수를 세는 자연수에서, 기준점(0)과 반대 방향(음수)을 나타내는 정수로의 확장을 배웁니다. 더불어 자바(Java) 등 타 언어에서 발생하는 메모리 한계(Overflow) 버그를 파이썬의 int 자료형이 어떻게 극복하고 무한대로 팽창하는지 그 위력을 확인합니다.
1. 음수 방향의 발명과 컴퓨터의 부호 비트(Sign Bit)
자연수(Natural Numbers: 1, 2, 3…)에 머물러 있던 초기 인류는 문명이 발달하면서 심각한 한계에 부딪혔습니다. 기온이 0도 아래로 꽁꽁 얼어붙을 때나, 친구에게 양 두 마리를 빌려 “빚”이 생겼을 때 이를 어떻게 숫자로 표기해야 할까요?
수학자들은 오랜 거부와 진통 끝에, 덧셈에 대한 항등원인 영($0$)을 기준점으로 삼아 반대 방향으로 뻗어 나가는 음수($-$)를 발명해 냈습니다. 이로써 자연수, 양의 정수, $0$, 음의 정수가 합쳐져 제로섬(Zero-Sum) 줄다리기를 하는 완벽한 수직선(Number Line) 위의 정수(Integers) 체계가 완성되었습니다.
컴퓨터는 ‘-‘ 마이너스 기호를 어떻게 저장할까?
컴퓨터 내부에는 물리적인 스위치($0$과 $1$)만 존재할 뿐, 인간이 쓰는 십자가 모양의 마이너스 기호(-) 부품 따위는 없습니다. 그렇다면 수직선의 이 ‘반대 방향’을 컴퓨터는 어떻게 물리적으로 구현해 냈을까요?
(다이어그램: 수직선의 양수/음수 방향성이 컴퓨터 바이트의 가장 첫 번째 스위치인 MSB(최상위 비트)에 의해 물리적 논리로 할당되는 원리)
컴퓨터 과학자들은 1바이트(8비트) 상자를 사용할 때, 가장 첫 번째 방(최상위 비트, MSB: Most Significant Bit)을 ‘부호 전용 스위치(Sign Bit)’로 약속했습니다.
- 첫 번째 스위치가
0(Off)이면: 수직선의 오른쪽으로 가는 양수(+) 방향을 의미합니다. - 첫 번째 스위치가
1(On)이면: 빚이 존재하거나 수직선의 왼쪽으로 가는 음수(-) 방향을 의미합니다.
결과적으로 파이썬의 정수형(int)은 단순한 양의 갯수 카운팅을 넘어서, 시스템 에러 코드(-1), 은행 계좌의 마이너스 통장 등 ‘음수 방향성’을 가진 데이터를 소수점 오차 없이 정확하게 추적하는 최고의 무기로 사용됩니다.
2. ☕ Java vs 🐍 Python: 정수의 메모리 한계 (Overflow)
프로그래밍에서 정수를 다룰 때 개발자들이 가장 뼈저리게 느끼는 고통이 있습니다. 바로 공간의 제약으로 숫자가 폭발해 버리는 오버플로우(Overflow)입니다.
(웹툰 비유: 4바이트 깡통 상자를 쓰다가 용량이 초과되어 폭발하는 자바 박스와, 고무처럼 쭉쭉 늘어나며 거대한 숫자를 우아하게 다 품어내는 파이썬 마법 주머니의 차이)
자바(Java)의 int 폭발
- C, C++, Java와 같은 언어는 극도의 메모리 계산 효율성을 추구하기 때문에 정수형
int에4 Bytes (32 bits)라는 딱 정해진 콘크리트 상자를 제공합니다. - 이 상자가 버틸 수 있는 최대 숫자는 대략 $21$억(
2,147,483,647)입니다. 만약 21억에서 $1$을 더해 상자가 넘치게 되면, 경계를 뚫고 가장 극단의 마이너스 수(-21억)로 수의 위상이 뒤집혀 버리는 치명적인 버그가 터집니다. 엄청 큰 수는 개발자가 직접 8 Bytes 크기의long타입으로 박스 크기를 새로 명시해주어야 합니다.
파이썬(Python)의 플렉시블(Flexible) int
- 반면 데이터 및 수학 분석에 특화된 파이썬의
int타입 단 한 개만 가지고도 10경, 100경, 구골플렉스 이상의 천문학적인 크기까지 계산이 가능합니다. - 파이썬 엔진(CPython)은 내부 배열 크기를 동적으로 늘려가면서, 컴퓨터 RAM 메모리가 버틸 수 있는 한 그 큰 정수를 제한 없이 모두 온전히 저장해 버리기 때문입니다. 오버플로우 개념 자체가 파이썬에서는 사실상 없습니다.
💡 잠깐만요, 파이썬은 호적 신고(int)를 안 하나요?
자바(Java)나 C언어에서는 정수를 만들 때 반드시 앞에 int money = 10000; 처럼 자료형(호적)을 먼저 선언해주어야 합니다. 하지만 파이썬은 동적 타입(Dynamic Typing)이라는 마법을 씁니다. 그냥 변수에 숫자 10000을 던져 넣으면, 파이썬 엔진이 “아, 소수점이 없는 숫자네? 이 녀석의 호적은 int구나!” 하고 스스로 알아서 int 객체로 포장해 줍니다.
그렇다면 파이썬에서 int 키워드는 언제 쓸까요?
파이썬의 int()는 주로 외부에서 들어온 텍스트 글자형태의 숫자(str)나, 소수점이 있는 실수(float)의 껍데기를 강력하게 벗겨내어 순수한 정수로 탈바꿈(Type Casting, 형변환)시킬 때 사용하는 매우매우 중요한 마법 지팡이(함수)로 쓰입니다.
# 일반 변수 생성 (알아서 int로 만들어줌)
count = 5
print("스스로 판단한 타입:", type(count)) # <class 'int'>
# int() 지팡이를 휘둘러서 정수로 강제 변환!
text_number = "100" # 화면 입력으로 받은 글자 "100"
float_number = 3.1415 # 소수점이 달린 실수
print("\n--- int() 마법 지팡이 사용 결과 ---")
print("1. 글자를 정수로 변경:", int(text_number) + 50) # 연산이 됨!
print("2. 실수를 정수로 변경:", int(float_number)) # 소수점 아래는 무참히 잘림 (3)
3. 무한의 팽창력 실습
파이썬의 동적 메모리 확장 기능을 맹신하고 우주의 크기만큼 큰 숫자를 정말로 만들 수 있는지 실습을 통해 증명해 봅시다.
# 1. 일반적인 덧셈이나 뺄셈, 정수 확인
money = 10000
debt = -25000
print("현재 자산:", money + debt) # 음수 연산 처리
# 2. 파이썬의 무한대 계산 (거듭제곱 연산자 ** 활약)
# 10의 100제곱 (1 뒤에 0이 100개 붙는 구골, Googol)
googol = 10 ** 100
print(f"구골(Googol) 출력:\n{googol}")
print("구골의 자료형:", type(googol))
# 3. 만약 자바였다면 바로 에러가 나거나 음수가 되지만, 파이썬은...
print("\n거대 숫자에 1을 더하면?")
print(googol + 1)
출력 예측: 1 뒤에 무수한 0이 찍힌 뒤, 마지막에 1이 더해진 완벽한 연산 결과가 에러 메시지 하나 없이 깔끔하게 터미널 창을 채웁니다.
🌌 참고: 구골(Googol)과 구골플렉스(Googolplex)란? 구골(Googol)은 1920년에 수학자 에드워드 캐스너의 어린 조카가 우연히 지어낸 단어로, 공식 수식으론 $10^{100}$ (1 뒤에 0이 100개 붙는 엄청난 수)을 뜻합니다. 전 우주의 모든 입자 수보다도 많은 개수죠. 구골플렉스(Googolplex)는 여기서 এক 차원 더 도약한, $10^{\text{Googol}}$ (즉 $10^{(10^{100})}$)을 뜻합니다. 인간의 상상을 벗어날 만큼 무한히 광대한 개수이자, 세계 최대 검색 엔진 회사인 ‘구글(Google)’ 이름의 실제 어원이 된 단어이기도 합니다. 원칙적으로 파이썬
int자료구조는 컴퓨터의 물리적 메모리(RAM)만 허용해 준다면 이 구골플렉스 숫자조차 오차 없이 그대로 계산해 담아낼 수 있는 무시무시한 잠재력을 품고 설계되었습니다.
4. 코딩 영단어 학습 📝
Integer(int): 완전한 것. 수학이야기(#41) 정수 편에서 배운 소수점이 없는 깨끗한 수를 뜻합니다. 영단어 “Entire(전체의)”와 어원이 동일합니다.Overflow: 넘쳐 흐르다. 그릇(변수의 메모리 사이즈)의 용량을 초과하는 숫자를 담을 때 발생하는 컴퓨터 시스템의 치명적인 한계 버그를 지칭합니다. 파이썬int는 이 공포에서 자유롭습니다.