본문 바로가기
Computer Science/Computer Architecture

[ 혼자 공부하는 컴퓨터구조 + 운영체제 ] Chapter02. 데이터

by seoyeonnn 2024. 4. 26.

02-1. 0과 1로 숫자를 표현하는 방법

컴퓨터는 0과 1로 모든 정보를 표현하고, 0과 1로 표현된 정보만을 이해한다. 이번 절에서는 컴퓨터가 표현하는 정보 단위를 학습하고, 0과 1만으로 숫자를 표현하는 방법에 대해 학습한다.

 

(1) 정보 단위

비트: 0과 1을 나타내는 가장 작은 정보 단위

비트는 전구에 빗대어 생각할 수 있는데, 전구 한 개로 (꺼짐) 혹은 (켜짐), 두 가지 상태를 표현할 수 있듯

비트는 0 또는 1, 두 가지 정보를 표현할 수 있으며 n 비트는 2$^n$가지 정보를 표현할 수 있다.

 

프로그램의 크기를 말할 때는 표현의 편의를 위해 비트보다 큰 단위를 사용한다.

 

바이트(byte): 여덟 개의 비트를 묶은 단위 (1바이트 = 8비트)

- 1바이트는 2$^8$(256)개의 정보를 표현할 수 있다.

킬로바이트(kB): 1바이트 1000개를 묶은 단위

메가바이트(MB): 1킬로바이트 1000개를 묶은 단위

기가바이트(GB): 1메가바이트 1000개를 묶은 단위

테라바이트(TB): 1기가바이트 1000개를 묶은 단위

 

워드(word)

: CPU가 한 번에 처리할 수 있는 데이터 크기

- CPU가 한 번에 16비트를 처리할 수 있다면 1워드는 16비트

하프 워드(half word): 워드의 절반 크기

풀 워드(full word): 1배 크기

더블 워드(double word): 2배 크기

- 현대 컴퓨터의 워드 크기는 대부분 32비트 또는 64비트

 

(2) 이진법

이진법: 1을 넘어가는 시점에 자리 올림을 하여 0과 1만으로 모든 수를 표현하는 방법

- 이진수: 이진법으로 표현한 수

십진법: 숫자가 9를 넘어가는 시점에 자리 올림을 하여 0부터 9까지, 열 개의 숫자만으로 모든 수를 표현하는 방법

- 십진수: 십진법으로 표현한 수

 

숫자만으로는 이 수가 어떤 진법으로 표현된 수인지 알 수 없기 때문에, 이진수 끝에 아래첨자 $_{(2)}$를 붙이거나 이진수 앞에 0b를 붙인다.

Ex) 이진수 8 표기 -> 1000$_{(2)}$, 0b1000

0과 1밖에 모르는 컴퓨터에 어떤 숫자를 알려 주려면 십진수가 아닌 이진수로 알려 주어야 한다.

 

이진수의 음수 표현 방법 중 가장 널리 사용되는 방법은 2의 보수를 구해 이 값을 음수로 간주하는 방법이다.

2의 보수: 어떤 수를 그보다 큰 2$^n$에서 뺀 값

Ex) 11$_{(2)}$의 2의 보수는 11$_{(2)}$보다 큰 2$^n$, 즉 100$_{(2)}$에서 11$_{(2)}$를 뺀 01$_{(2)}$이 된다.

 

이는 모든 0과 1을 뒤집고, 거기에 1을 더한 값으로 쉽게 표현할 수 있다.

Ex) 11$_{(2)}$의 모든 0과 1을 뒤집으면 00$_{(2)}$이고, 거기에 1을 더한 값은 01$_{(2)}$이기 때문에, 11$_{(2)}$의 2의 보수(음수 표현)는 01$_{(2)}$이다.

1의 보수: 모든 이진수의 0과 1을 뒤집은 수

 

어떤 수의 음수를 두 번 구하면 처음의 그 수가 되는 것처럼, 어떤 수의 2의 보수를 두 번 구하면 자기 자신이 된다.

 

이진수만 봐서는 음수인지 양수인지 구분하기 어렵기 때문에, 컴퓨터 내부에서는 어떤 수를 다룰 때 이 수가 양수인지 음수인지 구분하기 위해 플래그를 사용한다.

플래그(flag)는 쉽게 말해 부가 정보로, 컴퓨터 내부에서 어떤 값을 다룰 때 부가 정보가 필요한 경우 플래그를 사용한다.

 

※ 2의 보수 표현의 한계

- 0을 음수로 표현하면 자리 올림이 발생한 비트의 1을 버린다.

- $2^n$ 형태의 이진수에 보수를 취하면 자기 자신이 되어버리는 문제가 발생한다.

 

(3) 십육진법

십육진법: 수가 15를 넘어가는 시점에 자리 올림하여 수를 표현하는 방법

십진수 10, 11, 12, 13, 14, 15를 십육진법 체계에서는 각각 A, B, C, D, E, F로 표기한다.

 

한 글자로 열여섯 종류(0~9, A~F)의 정보를 표현할 수 있으니, 이진수에 비해 더 적은 자릿수로 더 많은 정보를 표현할 수 있다.

이진수와 마찬가지로 숫자 뒤에 아래첨자 $_{(16)}$를 붙이거나 숫자 앞에 0x를 붙여 구분한다.

 

십육진법을 사용하는 주된 이유 중 하나는 이진수를 십육진수로, 십육진수를 이진수로 변환하기 쉽기 때문이다.

2$^4$=16이기 때문에 십육진수를 이루는 숫자 하나를 이진수로 표현하려면 4비트가 필요하다.

십육진수를 이진수로 변환하는 간편한 방법은 십육진수 한 글자를 4비트의 이진수로 변환하고 이어 붙이는 것이다.

 

반대로 이진수를 십육진수로 변환할 때는 이진수 숫자를 네 개식 끊고, 끊어 준 네 개의 숫자를 하나의 십육진수로변환한 뒤 이어 붙이면 된다.

 

 

02-2. 0과 1로 문자를 표현하는 방법

(1) 문자 집합과 인코딩

문자 집합: 컴퓨터가 인식하고 표현할 수 있는 문자의 모음

문자 인코딩: 컴퓨터가 이해할 수 있도록 문자를 0과 1로 변환하는 과정

문자 코드: 인코딩후 0과 1로 이루어진 결과값

문자 디코딩: 인코딩의 반대 과정으로, 0과 1로 이루어진 문자 코드를 사람이 이해할 수 있는 문자로 변환하는 과정

 

(2) 아스키 코드

아스키(ASCII): 초창기 문자 집합 중 하나로, 영어 알파벳과 아라비아 숫자, 일부 특수 문자를 포함

아스키 문자(아스키 문자 집합에 속한 문자)는 각각 7비트로 표현되어, 총 128개의 문자를 표현할 수 있다.

 

※ 실제로는 하나의 아스키 문자를 나타내기 위해 8비트를 사용하나, 1비트는 패리티 비트(parity bit)라고 불리는, 오류 검출을 위해 사용되는 비트이기 때문에 실질적으로 문자 표현을 위해 사용되는 비트는 7비트이다.

 

아스키 코드: 아스키 문자에 대응된 고유한 수

아스키 코드는 매우 간단하게 인코딩된다는 장점이 있지만, 한글을 표현할 수 없으며 128개보다 많은 문자를 표현할 수 없다는 단점이 있다.

아스키 코드에 1비트를 추가한 8비트의 확장 아스키가 등장하기도 했지만, 여전히 부족했다.

 

(3) EUC-KR

한글 인코딩에는 두 가지 방식, 완성형(한글 완성형 인코딩)과 조합형(한글 조합형 인코딩)이 존재한다.

 

완성형 인코딩: 초성, 중성, 종성의 조합으로 이루어진 완성된 하나의 글자에 고유한 코드를 부여하는 인코딩 방식

Ex) '가': 1, '나': 2, '다':3

조합형 인코딩: 초성을 위한 비트열, 중성을 위한 비트열, 종성을 위한 비트열을 할당하여 그것들의 조합으로 하나의 글자 코드를 완성하는 인코딩 방식

 

EUC-KR: KS X 1001, KS X 1003이라는 문자 집합을 기반으로 하는 대표적인 완성형 인코딩 방식

초성, 중성, 종성이 모두 결합된 한글 단어에 2바이트 크기의 코드를 부여, 즉 EUC-KR로 인코딩된 한글 한 글자를 표현하려면 16비트가 필요하다. 16비트는 네 자리 십육진수로 표현할 수 있기 때문에, EUC-KR로 인코딩된 한글은 네 자리 십육진수로 나타낼 수 있다.

 

EUC-KR 인코딩 방식으로 총 2,350개 정도의 한글 단어를 표현할 수 있다.

이는 모든 한글 조합을 표현할 수 있는 정도의 많은 양이 아니기 때문에, 문자 집합에 정의되지 않은 글자는 표현할 수 없다.

 

이러한 문자를 조금이나마 해결하기 위해 등장한 것이 마이크로소프트의 CP949이다.

CP949: EUC-KR의 확장된 버전으로, EUC-KR로는 표현할 수 없는 더욱 다양한 문자를 표현할 수 있지만, 이마저도 한글 전체를 표현하기에 넉넉한 양은 아니다.

 

(4) 유니코드와 UTF-8

유니코드: EUC-KR보다 훨씬 다양한 한글을 포함하며 대부분 나라의 문자, 특수문자, 화살표나 이모티콘까지도 코드로 표현할 수 있는 통일된 문자 집합

현대 문자를 표현할 때 가장 많이 사용되는 표준 문자 집합으로, 문자 인코딩 세계에서 매우 중요한 역할을 맡고 있다.

 

※ 유니코드 문자 글자에 부여된 값 앞에 U+라는 문자열을 붙이기도 하는데, 이는 십육진수로 유니코드를 표현할 때 사용하는 표기이다.

 

아스키 코드나 EUC-KR은 글자에 부여된 값을 그대로 인코딩 값으로 삼았던 반면, 유니코드는 글자에 부여된 값 자체를 인코딩된 값으로 삼지 않고 이 값을 다양한 방법으로 인코딩한다. 이런 인코딩 방법에는 크게 UTF-8, UTF-16, UTF-32 등이 있다.

 

UTF-8: 가장 대중적인 유니코드를 인코딩하는 방식으로, 1바이트부터 4바이트까지의 인코딩 결과를 만들어 낸다.

유니코드 문자에 부여된 값의 범위에 따라 UTF-8로 인코딩한 결과가 몇 바이트가 될지 정해진다.

Ex)

'한'에 부여된 값은 D55C$_{(16)}$로, 0800$_{(16)}$과 FFFF$_{(16)}$ 사이에 있기 때문에 인코딩하면 3바이트로 표현될 것을 예상할 수 있다.

붉은색 X표가 있는 곳에 유니코드 문자에 부여된 고유한 값이 들어가는데, D55C$_{(16)}$은 이진수로 1101 0101 0101 1100$_{(2)}$이기 때문에, UTF-8 방식으로 인코딩한 결과는 11001101 10010101 10011100$_{(2)}$가 된다.