같은 비트라도 어떻게 읽기로 약속했느냐에 따라 -1도 되고 65535도 됩니다.
메모리에 11111111 11111111 이 들어 있습니다. 이건 얼마일까요?
- 부호 없는 수로 읽으면 → 65535
- 부호 있는 수로 읽으면 → -1
- 글자로 읽으면 → 깨진 문자
비트 자체에는 뜻이 없습니다. 어떻게 읽기로 약속했는지가 전부예요.
이 약속을 헷갈리면 쇼핑몰에서 주문 금액이 음수가 되는 사고가 납니다.
음수를 만드는 법 — 2의 보수
비트에는 마이너스 기호가 없습니다. 그래서 이렇게 약속했어요.
왜 이렇게 이상하게 만들었을까요? 뺄셈기를 따로 만들 필요가 없어지기 때문입니다.
5 - 3 을 5 + (-3) 으로 계산해도 덧셈기 하나로 답이 맞아떨어져요. 회로가 절반으로 줄어듭니다.
미니 CPU로 오버플로를 직접 일으켜 봅시다
아래는 이 강의에서 쓰는 미니 CPU의 어셈블리입니다.
16비트 레지스터라서 32767을 넘으면 음수로 돌아버려요. ▶ 실행을 눌러 보세요.
결과가 -32536 이 나왔을 겁니다. 33000은 16비트 부호 있는 수의 최댓값(32767)을 넘거든요.
CPU는 V(오버플로) 플래그를 세워서 "넘쳤다"고 알려 주지만,
프로그램이 그 플래그를 확인하지 않으면 그냥 음수인 채로 넘어갑니다.
그래서 실무에서는 돈은 넉넉한 정수 타입(64비트)이나 고정소수점으로 다룹니다.
실수는 왜 항상 조금 틀릴까
파이썬에서 0.1 + 0.2 를 해 보면 0.30000000000000004 가 나옵니다.
버그가 아니라 2진법으로는 0.1을 정확히 적을 수 없기 때문입니다.
10진법으로 1/3을 0.3333… 이라고 영원히 적어야 하는 것과 같아요.
한글은 몇 바이트인가
영어 한 글자는 1바이트(ASCII)입니다. 그런데 한글은요?
지금 표준인 UTF-8에서 한글 한 글자는 3바이트입니다.
그래서 DB에 VARCHAR(10)이라고 잡아 놓고
"열 글자 들어가겠지" 했다가 세 글자만 들어가는 사고가 나요.
한글 한 글자 = 3바이트. 자르는 위치를 잘못 잡으면 깨집니다.
🤔 확인 문제
8비트 부호 있는 정수에 저장된 재고가 -128 입니다. 여기서 1을 더 빼면?
해설 8비트 부호 있는 수의 범위는 -128 ~ 127 입니다. -128에서 1을 빼면 한 바퀴 돌아 127이 돼요. 대부분의 CPU는 조용히 넘어가고 V 플래그만 세웁니다 — 프로그램이 확인하지 않으면 아무도 모르죠.
🤔 확인 문제
쇼핑몰 DB에 상품 설명을 VARCHAR(30)으로 잡았는데 한글 12자를 넣으니 거절당했습니다. 가장 그럴듯한 원인은?
해설 DB가 길이를 바이트로 세는 설정이면 한글 12자 = 36바이트라 넘칩니다. 그래서 요즘 MySQL은 utf8mb4 + 문자 단위로 세도록 설정하는 게 기본이에요.