정의
정수 오버플로(Integer Overflow)는 컴퓨터가 숫자를 저장하기 위해 정해둔 메모리 그릇의 최대 크기를 넘어섰을 때 일어나는 계산 오류예요. 담을 수 있는 한계를 넘어서는 순간, 숫자가 엉뚱한 값(흔히 음수나 0)으로 바뀌어 버려요.
자동차 계기판이 9999에서 0000이 되는 이유
자동차가 달린 거리를 숫자로 표시하는 아날로그 계기판을 떠올려 보세요. 네 자리 숫자를 표시하는 계기판은 최대 9999까지만 적을 수 있어요.
여기서 1km를 더 달리면 계기판은 10000을 보여주지 못해요. 다섯 번째 자릿수를 적을 물리적인 공간이 없기 때문에, 맨 앞의 1은 허공으로 사라지고 결국 0000으로 돌아가 버립니다.
컴퓨터 내부에서도 똑같은 원리로 작동해요. 컴퓨터는 숫자를 저장할 때 메모리 공간의 크기를 미리 정해둬요. 8개, 32개, 64개처럼 정해진 개수의 비트(0과 1을 담는 방)를 사용하죠. 그 방에 1을 꽉 채운 상태에서 숫자를 하나 더 더하면, 자릿수가 넘쳐흐르면서 컴퓨터는 맨 앞자리를 버리고 말아요.
조금 더 정확히 말하면: 왜 갑자기 음수가 될까요?
단순히 0이 되는 것보다 프로그래밍에서 훨씬 더 흔하고 위험한 현상은 양수가 갑자기 거대한 음수로 뒤집히는 것이에요.
조금 더 정확히 말하면, 컴퓨터는 양수와 음수를 모두 다루기 위해 숫자의 가장 앞자리 비트 하나를 '부호 표시용'으로 사용해요. 이 자리가 0이면 양수이고, 1이면 음수를 뜻하죠.
예를 들어 32비트 정수 공간에서 표현할 수 있는 가장 큰 양수는 약 21억(2,147,483,647)이에요. 여기에 1을 더하면 숫자가 21억 1이 되는 것이 아니라, 비트 계산 규칙 때문에 맨 앞의 부호 비트가 0에서 1로 켜져 버려요. 대부분의 컴퓨터는 2의 보수라는 방식을 써서, 맨 앞 비트가 켜지면 약 -21억(-2³¹)이라는 큰 음수 값을 더하는 것과 같아요. 그 결과 컴퓨터는 이 값을 약 마이너스 21억으로 잘못 읽게 돼요. 게임에서 체력을 너무 많이 올려서 최대치를 넘겼더니 캐릭터가 즉사하거나, 통장에 돈을 넣었는데 빚쟁이가 되는 황당한 버그가 바로 여기서 생겨요.
현실 세계를 뒤흔든 오버플로 사건들
이 현상은 단순한 교과서 속 이론이 아니에요. 실제로 수많은 서비스와 현실 세계를 발칵 뒤집어 놓은 역사적인 사건들이 많아요.
가장 널리 알려진 사례가 유튜브의 '강남스타일' 조회수 사건이에요. 유튜브는 처음에 조회수를 저장하는 변수로 32비트 정수(최대 약 21억)를 썼어요. 그런데 싸이의 강남스타일 뮤직비디오가 폭발적인 인기를 끌며 조회수가 이 한도에 다가가자, 유튜브 엔지니어들은 한도를 넘기 몇 달 전에 미리 64비트 정수로 저장 공간을 교체해 최대 한도를 약 922경으로 늘려 두었어요. 2014년 12월 유튜브가 이 일을 강남스타일 때문이라며 농담 섞어 공개하면서 널리 알려졌죠.
훨씬 더 비극적인 사건도 있었어요. 1996년 막대한 비용이 들어간 유럽의 아리안 5호 우주 로켓은 발사 약 40초 만에 공중에서 부서졌어요. 속도 관련 데이터(64비트 실수)를 16비트 정수로 바꾸다 오버플로가 나 관성항법장치가 멈췄고, 비행 컴퓨터가 그 장치의 오류 신호를 비행 데이터로 잘못 읽어 로켓이 비행 경로를 벗어났기 때문이에요.
흔한 오해
숫자가 그릇보다 커지면 컴퓨터가 즉시 오류(에러) 메시지를 띄우며 안전하게 멈춘다.
C/C++ 같은 언어에서는 에러 없이 값이 한 바퀴 돌거나(부호 없는 정수), 결과를 보장할 수 없는 상태(부호 있는 정수)가 돼요. 그래서 버그를 사전에 발견하기가 매우 어렵고 위험해요. 반대로 Swift는 오버플로를 감지하면 프로그램을 멈추고, Rust는 디버그 빌드에서는 멈추지만 기본 릴리스 빌드에서는 값이 한 바퀴 돌아요.
일상에서 만나요
유튜브 조회수가 32비트 한도(약 21억 회)에 다가가자 미리 64비트로 업그레이드한 일화예요.
게임에서 소지금이 최대 한도를 넘는 순간 갑자기 0원이 되거나 마이너스 통장으로 변하는 버그예요.
아리안 5호 우주 로켓이 속도 관련 데이터를 16비트 정수로 바꾸다 오버플로가 나 항법장치가 멈추고 비행 경로를 벗어나 부서진 사고예요.
그러니까 한마디로
컴퓨터가 정해둔 숫자의 최대 그릇을 넘어서면, 숫자가 엉뚱한 값(흔히 음수나 0)으로 뒤집히는 계산 오류예요.