정수와 비트 표현

Jaemyeong Lee·2024년 7월 4일

게임 서버1

목록 보기
10/220

이번 Step에서 잡아야 할 것

  • bit / byte: 저장 단위의 기본
  • 2의 보수(two's complement): 음수를 비트로 표현하는 표준 방식
  • 진법(2/10/16): 코드에서 숫자를 읽는 법
  • 오버플로우: 범위를 넘으면 값이 깨지고, 실제 게임/코테 버그로 이어짐

Bit, Byte

  • 1 bit: 0 또는 1 (전기 신호 유무)
  • 1 byte: 8 bit

비트 8개가 모이면 1바이트이고, 정수 타입은 “몇 바이트를 쓰는지”에 따라 범위가 결정됩니다.

2의 보수 (음수 표현)

대부분의 컴퓨터는 2의 보수로 음수를 표현합니다.
(signed 정수에서) 가장 왼쪽 비트는 흔히 부호 비트(sign bit)로 해석됩니다.

1바이트(8비트) signed 기준으로 보면:

비트:  b7 b6 b5 b4 b3 b2 b1 b0
값  : (부호/가중치) +64 +32 +16  +8  +4  +2  +1
  • 01111111 = 127
  • 10000000 = -128
    • “음수 담당”이라는 말은, 2의 보수 표현에서 최상위 비트가 1이면 음수로 해석된다는 뜻입니다.

양수 N을 음수 -N으로 바꾸는 방법(2의 보수):

  1. 모든 비트를 반전(0↔1)
  2. 1을 더한다

예: (43 \rightarrow -43) (8비트 예시)

  43  = 00101011
반전 = 11010100
 + 1 = 11010101  (= -43)

1바이트 범위

  • 최대: 01111111 = 127
  • 최소: 10000000 = -128

진법

진법설명코드
2진법0, 1만 사용0b1100
10진법일상 사용기본
16진법2진법과 궁합 (4비트=1자리)0xF

16진수는 “비트를 사람이 읽기 쉽게 압축한 표기”라고 생각하면 편합니다.

16진법

  • 0~9, A(10), B(11), C(12), D(13), E(14), F(15)
  • 2진수 4자리 = 16진수 1자리

예: 0x2B는 2진수로 0010 1011, 즉 10진수 43입니다.

0x2B
 = 0b0010 1011
 = 32 + 8 + 2 + 1
 = 43

오버플로우

  • 정수 타입은 담을 수 있는 범위가 정해져 있습니다.
  • 그 범위를 넘어가면 값이 깨집니다(오버플로우/잘림).

대표적인 두 가지 상황:

  • 연산 오버플로우: 범위를 넘어서는 덧셈/곱셈 등
    • 예: short에 30000 + 20000 → 50000이 아니라 엉뚱한 값
  • 대입(캐스팅) 잘림: 큰 타입 값을 작은 타입에 넣을 때 상위 비트가 잘림
    • 예: intshort로 대입하면 범위를 벗어나는 순간 다른 숫자가 됨

참고: C++에서 signed 정수 오버플로우는 표준상 정의되지 않은 동작(UB)입니다.
실전에서는 “대부분 2의 보수로 래핑되는 것처럼 보일 수 있지만”, 믿고 쓰면 위험합니다.

정수 오버플로우 (실제 사례)

  • 게임: HP/데미지/골드 같은 값이 타입 범위를 넘으면
    • 갑자기 음수가 되거나,
    • 비교/조건문이 뒤집혀서(예: “HP가 0 이하인가?”) 이상한 동작을 만들 수 있습니다.
  • 코딩 테스트: int 범위(약 21억)를 넘어가는 입력에서 정답이 틀리기 쉬움 → long long이 필요한 전형적인 케이스

체크 질문 (스스로 답해보기)

  • 2의 보수에서 “음수”를 만드는 규칙은 무엇이었나? (2단계)
  • 0x2B가 왜 43인지 스스로 계산할 수 있나?
  • 큰 값이 나올 수 있는 상황에서 int를 쓰면 어떤 종류의 문제가 생길까?

profile
李家네_공부방

0개의 댓글