수와 논리: 컴퓨터 수학의 첫걸음

컴퓨터와 AI 공부에 수학이 왜 필요한지, 수의 체계와 진법 변환, 명제와 논리 연산, 진리표, 드모르간 법칙까지 컴퓨터 수학의 가장 기초를 코드와 함께 익혀요.

입문강의 1 / 6약 7분

"수학을 못해도 개발할 수 있나요?"라는 질문을 자주 받아요. 웹사이트를 만드는 데는 사칙연산이면 충분할 때가 많아요. 하지만 AI를 이해하고, 성능을 분석하고, 데이터로 판단하려는 순간 수학은 피할 수 없는 언어가 돼요. 이 트랙은 고등학교 수학이 가물가물한 사람도 따라올 수 있게 처음부터 시작해요. 첫 강의는 모든 것의 바탕인 수와 논리예요.

컴퓨터 공부에 수학이 필요한 이유

이 가이드북의 AI 집중 코스에서 수학은 이렇게 쓰여요.

수학 분야컴퓨터와 AI에서 하는 일
논리와 집합조건문, 데이터베이스 검색, 회로 설계의 바탕
이산수학과 그래프알고리즘, 네트워크, 추천 시스템
선형대수데이터를 벡터와 행렬로 표현하고 한꺼번에 계산
미적분모델이 오차를 줄이며 스스로 학습하는 원리
확률과 통계불확실성을 다루고 결과를 믿을 수 있는지 판단

수학 공부의 목표는 계산을 빨리 하는 게 아니에요. 계산은 컴퓨터가 해요. 우리가 할 일은 수식이 말하는 뜻을 읽는 것이에요. 그래서 이 트랙에서는 공식을 외우기보다 "이 식이 무슨 이야기를 하는가"에 집중해요.

수의 체계

수는 필요에 따라 조금씩 넓어져 왔어요.

  • 자연수: 1, 2, 3, ... 물건을 셀 때 쓰는 수.
  • 정수: ..., -2, -1, 0, 1, 2, ... 빚이나 영하 온도처럼 0과 음수가 필요해서 생겼어요.
  • 유리수: 분수로 나타낼 수 있는 수. 1/2, -3/4, 0.75(= 3/4)처럼요.
  • 실수: 유리수에 2\sqrt{2}나 π\pi처럼 분수로 나타낼 수 없는 무리수까지 더한 수직선 위의 모든 수.

포함 관계를 기호로 쓰면 이래요.

N⊂Z⊂Q⊂R\mathbb{N} \subset \mathbb{Z} \subset \mathbb{Q} \subset \mathbb{R}

컴퓨터는 수를 어떻게 다루나

프로그래밍 기초에서 본 int와 float이 바로 이 구분이에요. 그런데 컴퓨터의 수는 수학의 수와 한 가지가 달라요. 메모리가 유한하다는 점이에요.

  • 파이썬의 int는 메모리가 허락하는 만큼 커질 수 있지만, 많은 언어의 정수는 크기가 정해져 있어요. 32비트 정수는 약 21억까지만 담을 수 있어서, 넘어가면 음수로 뒤집히는 오버플로가 생겨요.
  • float은 실수를 근사해서 저장해요. 그래서 0.1+0.20.1 + 0.2가 정확히 0.30.3이 되지 않았죠. 무리수는 애초에 끝없이 이어지니 정확히 저장할 방법이 없어요.

컴퓨터의 수는 수학의 수를 흉내 낸 유한한 근사라는 사실을 기억하면, 이상한 계산 결과를 만났을 때 당황하지 않아요.

진법: 같은 수, 다른 표기

우리가 쓰는 10진법은 자리마다 10배씩 커져요.

3507=3×103+5×102+0×101+7×1003507 = 3 \times 10^3 + 5 \times 10^2 + 0 \times 10^1 + 7 \times 10^0

컴퓨터는 전기가 흐르는지 안 흐르는지 두 상태로 정보를 저장해서 2진법을 써요. 자리마다 2배씩 커져요.

10112=1×23+0×22+1×21+1×20=8+0+2+1=111011_2 = 1 \times 2^3 + 0 \times 2^2 + 1 \times 2^1 + 1 \times 2^0 = 8 + 0 + 2 + 1 = 11

10진수를 2진수로 바꾸기

2로 계속 나누고 나머지를 거꾸로 읽어요. 13을 바꿔 볼게요.

나눗셈몫나머지
13 ÷ 261
6 ÷ 230
3 ÷ 211
1 ÷ 201

나머지를 아래에서 위로 읽으면 110121101_2예요. 검산하면 8+4+0+1=138 + 4 + 0 + 1 = 13이 맞아요.

16진수

2진수는 너무 길어서, 사람이 볼 때는 4자리씩 묶은 16진법을 써요. 0부터 9 다음에 A(10), B(11), C(12), D(13), E(14), F(15)를 써요.

1101 01102=D616=13×16+6=2141101\ 0110_2 = \text{D6}_{16} = 13 \times 16 + 6 = 214

웹 색상 코드 #FF8800이 바로 16진수예요. 빨강 FF(255), 초록 88(136), 파랑 00(0)이라는 뜻이에요.

print(bin(13))        # 0b1101
print(hex(214))       # 0xd6
print(int("1101", 2)) # 13
print(int("d6", 16))  # 214

자리 수와 표현 범위

2진수 nn자리로 표현할 수 있는 경우의 수는 2n2^n개예요. 이 계산은 컴퓨터 공부 내내 나와요.

비트 수경우의 수쓰임
12참과 거짓
8 (1바이트)256색상 한 채널(0~255)
1665,536포트 번호 범위
32약 43억IPv4 주소 전체 개수
64약 1,845경현대 컴퓨터의 기본 정수 크기

210=10242^{10} = 1024가 1000과 거의 같아서, 1024바이트를 1KB라고 부르게 됐어요.

명제와 논리

명제

참인지 거짓인지 분명하게 정할 수 있는 문장을 명제라고 해요.

  • "7은 소수다" → 명제(참)
  • "서울은 일본의 수도다" → 명제(거짓)
  • "이 영화는 재미있다" → 사람마다 달라서 명제가 아니에요

프로그래밍의 조건식 age >= 19도 실행하는 순간 참이나 거짓으로 정해지니 명제와 같아요.

논리 연산

명제 pp, qq를 이어서 새 명제를 만들어요.

연산기호파이썬뜻
부정¬p\lnot pnot pp가 아니다
논리곱p∧qp \land qp and qp이고 q다 (둘 다 참일 때만 참)
논리합p∨qp \lor qp or qp이거나 q다 (하나라도 참이면 참)
배타적 논리합p⊕qp \oplus qp != q둘 중 정확히 하나만 참

진리표

모든 경우를 표로 늘어놓으면 논리식이 언제 참인지 분명해져요. T는 참, F는 거짓이에요.

ppqqp∧qp \land qp∨qp \lor qp⊕qp \oplus q
TTTTF
TFFTT
FTFTT
FFFFF

조건문: 만약 p라면 q다

p→qp \to q는 "p이면 q다"예요. 진리표가 조금 의외예요.

ppqqp→qp \to q
TTT
TFF
FTT
FFT

p→qp \to q가 거짓인 경우는 p가 참인데 q가 거짓일 때 딱 하나예요. "비가 오면 우산을 쓴다"는 약속은 비가 왔는데 우산을 안 썼을 때만 깨져요. 비가 안 온 날에는 우산을 쓰든 말든 약속을 어긴 게 아니죠.

역, 이, 대우

p→qp \to q에서 파생되는 세 문장이 있어요.

  • 역: q→pq \to p
  • 이: ¬p→¬q\lnot p \to \lnot q
  • 대우: ¬q→¬p\lnot q \to \lnot p

원래 문장과 항상 진릿값이 같은 것은 대우뿐이에요. "사람이면 죽는다"가 참이면 "죽지 않으면 사람이 아니다"(대우)도 참이지만, "죽으면 사람이다"(역)는 참이 아니에요. 증명을 할 때 원래 문장이 어려우면 대우를 대신 증명하는 기술을 자주 써요.

드모르간 법칙

부정을 괄호 안으로 넣으면 and와 or가 뒤바뀌어요.

¬(p∧q)≡¬p∨¬q¬(p∨q)≡¬p∧¬q\lnot (p \land q) \equiv \lnot p \lor \lnot q \qquad \lnot (p \lor q) \equiv \lnot p \land \lnot q

"성인이고 회원이다"가 아니라는 말은 "성인이 아니거나 회원이 아니다"와 같아요. 코드를 정리할 때 아주 쓸모 있어요.

# 원래 조건
if not (age >= 19 and is_member):
    print("이용할 수 없어요")

# 드모르간으로 펼친 조건 (같은 뜻)
if age < 19 or not is_member:
    print("이용할 수 없어요")

복잡한 조건을 읽기 쉽게 바꾸거나, 두 조건이 정말 같은 뜻인지 확인할 때 진리표와 드모르간 법칙을 쓰세요.

논리를 비트로: 비트 연산

논리 연산은 2진수의 각 자리에도 적용할 수 있어요. 이걸 비트 연산이라고 해요.

a = 0b1100   # 12
b = 0b1010   # 10
print(bin(a & b))   # 0b1000  자리마다 AND
print(bin(a | b))   # 0b1110  자리마다 OR
print(bin(a ^ b))   # 0b110   자리마다 XOR
print(bin(a << 1))  # 0b11000 왼쪽으로 한 칸 (2배)

권한 관리처럼 여러 개의 켜짐과 꺼짐을 숫자 하나에 담을 때 써요. 리눅스 파일 권한의 755 같은 숫자도 사실 비트 묶음이에요(리눅스 트랙에서 다시 만나요).

연습 문제

  1. 10110210110_2를 10진수로 바꾸세요.
  2. 45를 2진수로 바꾸세요.
  3. 2진수 12자리로 표현할 수 있는 수는 몇 가지인가요?
  4. pp가 참, qq가 거짓일 때 ¬p∨q\lnot p \lor q의 값은?
  5. "로그인했고 관리자라면 수정할 수 있다"의 대우를 쓰세요.
  6. 드모르간 법칙으로 not (x > 0 or y > 0)을 not 없이 바꿔 보세요.

정답

  1. 16+4+2=2216 + 4 + 2 = 22
  2. 1011012101101_2 (32 + 8 + 4 + 1 = 45)
  3. 212=40962^{12} = 4096가지
  4. 거짓. ¬p\lnot p가 거짓이고 qq도 거짓이라 둘 다 거짓이에요. 참고로 ¬p∨q\lnot p \lor q는 p→qp \to q와 같은 식이에요.
  5. "수정할 수 없다면, 로그인하지 않았거나 관리자가 아니다."
  6. x <= 0 and y <= 0

다음 강의

다음 강의에서는 집합, 함수, 관계를 배워요. 집합은 데이터베이스 검색의 바탕이고, 함수는 수학과 프로그래밍과 AI를 하나로 잇는 가장 중요한 개념이에요. AI 모델도 결국 "입력을 받아 출력을 내는 거대한 함수"거든요.