이 글은 혼자 공부하는 컴퓨터 구조+운영체제 교재와 강의를 참고하여 정리한 글입니다. 오타나, 잘못된 내용이 있으면 언제든지 알려주세요! 감사합니다.😊
0과 1로 데이터를 표현하는 방법
0과 1로 숫자를 표현하는 방법
컴퓨터는 0과 1로 모든 정보를 표현하고, 0과 1로 표현된 정보만을 이해할 수 있다.
0과 1밖에 모르는데 어떻게 1보다 큰 수를 이해할 수 있을까?
컴퓨터가 이해하는 정보 단위
비트(bit)
- 비트는 0과 1을 표현할 수 있는 가장 작은 정보 단위이다.
- 예) 전구 꺼짐: 0, 전구 켜짐: 1
- n비트는 2n가지의 정보를 표현할 수 있다.
- 프로그램은 수많은 비트로 이루어져 있다.
- 다만, 평소에 프로그램의 크기를 말할 때 비트로 표현하지는 않는다.
- 프로그램의 크기를 말할 때는 비트보다 더 큰 단위를 사용한다.
- 1바이트(1byte) = 8비트(8bit)
- 1킬로바이트(1kB) = 1,000바이트(1,000byte)
- 1메가바이트(1MB) = 1,000킬로바이트(1,000kB)
- 1기가바이트(1GB) = 1,000메가바이트(1,000MB)
- 1테라바이트(1TB) = 1,000기가바이트(1,000GB)
- 바이트를 제외한 그 이상의 단위들은 모두 이전 단위를 1,000개씩 묶어 표현한 단위이다.
참고: 이전 단위를 1024개씩 묶은 단위는 KiB, MiB, GiB, TiB이다.
최근에는 1000개씩 묶은 단위와 1024개씩 묶은 단위를 구분해서 사용하고 있다.
워드
- 워드는 CPU가 한번에 처리할 수 있는 데이터(정보)의 크기 단위이다.
- 예) 만약 CPU가 한 번에 16비트를 처리할 수 있다면, 1워드는 16비트가 되는 것이다.
- 하프 워드(half word): 워드의 절반 크기
- 풀 워드(full word): 워드 크기
- 더블 워드 (double word): 워드의 2배 크기
이진법
이진법
- 이진법은 0과 1로 숫자를 표현하는 방법이다.
- 어떻게? 숫자가 1을 넘어가는 시점에 자리올림을 하면 된다
- 우리가 일상적으로 사용하는 진법은 십진법. 숫자가 9를 넘어갈 때 자리올림을 한다.
- 이진수: 이진법으로 표현한 수
- 십진수: 십진법으로 표현한 수
컴퓨터에게 어떤 숫자를 알려 주려면 십진수가 아닌 이진수로 알려주면 된다.
근데 숫자 10만 보고 십진수인지 이진수인지 구분할 수가 없다.
- 예) 숫자 10을 이진수로 읽으면 2이고, 십진수로 읽으면 10이다.
이러한 문제를 해결하기 위해 이진수 끝에 아래첨자(2)를 붙이거나, 이진수 앞에 0b를 붙인다.
- 예) 이진수 8표기 -> 1000(2), 0b1000
이진수의 음수 표현
컴퓨터는 0과 1만 이해할 수 있기 때문에('-' 마이너스 부호 인식 못함), 0과 1만으로 음수를 표현해야 한다.
0과 1만으로 음수를 어떻게 표현할까? 가장 대표적으로 사용되는 방법은 2의 보수를 구해 이 값을 음수로 간주한다.
2의 보수법
- 2의 보수의 사전적 의미는 '어떤 수를 그보다 큰 2n에서 뺀 값'을 의미한다.
- 예) 11(2)의 2의 보수는, 11(2)보다 큰 2n, 즉 100(2)에서 11(2)을 뺀 01(2)이 되는 것이다.
사전적 의미로 어렵게 이해하지 말고 더 쉬운 방법으로 이해하자.
2의 보수를 쉽게 표현하면 '모든 0과 1을 뒤집고, 거기에 1을 더한 값'이다.
예시)
- 11(2)의 모든 0과 1을 뒤집으면, 00(2)이 된다. 여기에 1을 더한 값은 01(2)이다.
- 즉, 11(2)을 음수로 표현한 값은 01(2)이 되는 것이다.
정말로 구한 값이 음수인지 확인해 보자.
어떤 수의 음수를 두 번 구하면 원래 수가 된다. -(-A) = A
예시)
- 1011(2)의 모든 0과 1을 뒤집으면, 0100(2)이 된다. 여기에 1을 더한 값은 0101(2)이다.
- 0101(2)의 모든 0과 1을 뒤집으면, 1010(2)이 된다. 여기에 1을 더한 값은 1011(2)이다.
- 2의 보수를 두번 구하니 자기 자신인 1011(2)이 되는 것을 확인할 수 있다.
근데 -1011(2)를 표현하기 위한 음수로서의 0101(2)과 십진수 5를 표현하기 위한 양수로서의 0101(2) 두 개를 어떻게 구분할까?
컴퓨터 내부에서 플래그를 사용하여 양수인지 음수인지를 구분한다.
플래그
- 플래그는 CPU 내부에 있는 플래그 레지스터에 표시되는 값으로, 이 값을 통해 숫자가 양수인지 음수인지를 구분한다.
- 모든 숫자가 플래그 값(양수, 음수)을 들고 다닌다고 생각하면 된다
2의 보수 표현의 한계
- 2의 보수는 현재까지 가장 대표적으로 사용되는 방식이지만, 완벽한 방식은 아니다.
- 0이나 2n 형태의 이진수에 2의 보수를 취하면 원하는 음수값을 얻을 수 없기 때문이다.
- 예시 1)
- 0을 음수로 표현해 보자
- 0000(2)의 모든 0과 1을 뒤집으면 1111(2)이 된다. 여기에 1을 더한 값은 10000(2)이다.
- 이 경우에는 자리 올림이 발생한 비트의 1을 버린다.
- 예시 2)
- 23을 음수로 표현해 보자
- 1000(2)의 모든 0과 1을 뒤집으면 0111(2)이 된다. 여기에 1을 더한 값은 1000(2)이다.
- 음수로 표현한 값이 양수로 표현한 값과 같다.
- 즉, n비트로는 -2n과 2n이라는 수를 동시에 표현할 수 없다.
이진법을 이용해 0과 1만으로도 모든 숫자를 표현할 수 있다.
하지만, 0과 1만으로 모든 숫자를 표현해 숫자의 길이가 너무 길어진다는 단점이 있다.
예) 십진수 32를 이진수로 표현하면 100000(2)
따라서, 데이터를 표현할 때 십육진법도 자주 사용하게 된다.
십육진법
- 십육진법은 수가 15를 넘어가는 시점에 자리 올림을 하는 숫자 표현 방식이다.
십육진수도 이진수와 마찬가지로 숫자 뒤에 아래첨자(16)를 붙이거나, 숫자 앞에 0x를 붙여 구분한다.
- 예시) 십육진수 15 표기
- 15(16): 수학적 표기방식
- 0x15: 코드상 표기 방식
참고: 코드에 십육진수를 직접 코드에 써넣는 경우도 많이 있다.
십육진법은 왜 사용할까?
가장 주된 이유는 이진수 -> 십육진수, 십육진수 -> 이진수로 변환하기 쉽기 때문이다.
십육진수를 이진수로 변환하기
- 십육진수를 이루는 숫자 하나를 이진수로 표현하려면 4비트가 필요하다. (24 = 16)
- 십육진수 한 글자를 4비트의 이진수로 간주하면 된다.
- 즉, 십육진수의 각 글자를 이진수로 변환하고, 그대로 이어 붙이면 십육진수가 이진수로 변환된다.
- 예시)
- 1A2B(16) 십육진수가 있다고 가정하자.
- 1(16)를 이진수로 변환하면 0001(2)이다.
- A(16)를 이진수로 변환하면 1010(2)이다.
- 2(16)를 이진수로 변환하면 0010(2)이다.
- B(16)를 이진수로 변환하면 1011(2)이다.
- 그대로 이어 붙이면 0001101000101011(2)이 되고, 십육진수 1A2B(16)를 이진수로 변환한 값이다.
이진수를 십육진수로 변환하기
- 이진수 숫자를 네 개씩 끊고, 끊은 네 개의 숫자를 하나의 십육진수로 변환한 뒤 그대로 이어 붙이면 이진수가 십육진수로 변환된다.
- 예시)
- 11010101(2)이라는 이진수가 있다고 가정하자.
- 네 개씩 끊으면 1101(2)과 0101(2)이다.
- 1101(2)를 십육진수로 변환하면 D(16)이다.
- 0101(2)를 십육진수로 변환하면 5(16)이다.
- 그대로 이어 붙이면 D5(16)가 되고, 이진수 11010101(2)를 십육진수로 변환한 값이다.
0과 1로 문자를 표현하는 방법
컴퓨터는 0과 1로 모든 정보를 표현하고, 0과 1로 표현된 정보만을 이해할 수 있다.
0과 1밖에 모르는데 어떻게 문자를 이해하고 표현할 수 있을까?
문자 집합과 인코딩
- 문자 집합 (character set)
- 컴퓨터가 이해할 수 있는 문자의 모음
- 컴퓨터는 문자 집합에 속해 있는 문자를 이해할 수 있고, 반대로 문자 집합에 속해 있지 않은 문자는 이해할 수 없다.
- 예) 문자 집합: {a, b, c, d, e} 일 경우 a, b, c, d, e는 이해 가능하지만 x, y, z 같은 문자는 이해할 수 없다.
- 문자 인코딩 (encoding)
- 코드화하는 과정
- 문자 집합에 속한 문자를 0과 1로 이루어진 문자 코드로 변환하는 과정
- 예) Hello -> 01001000...
- 문자 디코딩 (decoding)
- 인코딩의 반대
- 코드를 해석하는 과정
- 0과 1로 표현된 문자 코드(인코딩 된 문자 코드)를 문자(우리가 이해할 수 있는)로 변환하는 과정
- 예) 01001000... -> Hello
대중적으로 사용되는 문자 집합에는 어떤 것이 있을까?
아스키 코드
- 아스키는 초창기 문자 집합 중 하나이다.
- 알파벳, 아라비아 숫자, 일부 특수 문자 및 제어 문자를 포함한다.
- 7비트로 하나의 문자를 표현한다.
- 실제로는 하나의 아스키 문자를 표현하기 위해 8비트를 사용한다.
- 8비트 중 1비트는 오류 검출을 위해 사용되는 패리티 비트(parity bit)이다.
- 실질적으로 문자 표현을 위해 사용되는 비트는 7비트이다.
- 7비트로 표현할 수 있는 정보의 가짓수는 27개로, 총 128개의 문자를 표현할 수 있다.
아스키 코드표
- 아스키 문자들은 0부터 127까지 총 128개의 숫자 중 하나의 고유한 수에 일대일로 대응된다.
- 아스키 문자에 대응된 고유한 수를 아스키 코드라고 한다.
- 즉, 아스키 문자 집합에 0부터 127까지의 수가 할당되어 아스키 코드로 인코딩 되는 것이다.
- 예) 'A'는 십진수 65 (이진수 1000001(2))로 인코딩 된다.
참고: 문자 인코딩에서 '글자에 보유된 고유한 값'을 코드 포인트(code point)라고 한다.
예) 아스키 문자 A의 코드 포인트는 65이다.
이처럼 아스키 코드는 매우 간단하게 인코딩 된다는 장점이 있다. 하지만 단점도 존재한다.
한글을 포함한 다른 언어 문자, 다양한 특수 문자를 표현할 수 없다.
- 아스키 문자 집합에 속한 문자들은 7비트로 표현한다.
- 즉, 128개보다 많은 문자를 표현할 수 없다.
- 더 다양한 문자 표현을 위해 아스키 코드에 1비트를 추가한 8비트의 확장 아스키가 등장했지만, 여전히 부족하다.
따라서 나라별 자신들의 언어를 0과 1로 표현할 수 있는 고유한 문자 집합과 인코딩 방식이 등장하였다.
우리나라의 한글 인코딩 방식은 EUC-KR이다.
EUC-KR
영어는 알파벳을 쭉 이어 쓰면 단어가 된다. 예) apple
하지만, 한글은 초성, 중성, 종성의 조합으로 이루어져 있다.
그래서 한글 인코딩에는 완성형(한글 완성형 인코딩)과 조합형(한글 조합형 인코딩) 두 가지 방식이 존재한다.
완성형 인코딩 방식
- 초성, 중성, 종성의 조합으로 이루어진 완성된 하나의 글자에 고유한 코드를 부여하는 인코딩 방식이다.
조합형 인코딩 방식
- 초성을 위한 비트열, 중성을 위한 비트열, 종성을 위한 비트열을 할당하여 그것들의 조합으로 하나의 글자 코드를 완성하는 인코딩 방식이다.
EUC-KR
- KS X 1001, KS X 1003이라는 문자 집합을 기반으로 하는 한글 완성형 인코딩 방식이다.
- 초성, 중성, 종성이 모두 결합된 한글 단어(글자 하나하나)에 2바이트 크기의 코드를 부여한다.
- 2바이트 == 16비트 == 4자리 십육진수로 표현
- 즉, EUC-KR로 인코딩 된 한글 한 글자를 표현하려면 16비트가 필요하고, 4자리 십육진수로 표현할 수 있다.
- 2,350개 정도의 한글 단어를 표현할 수 있지만, 여전히 모든 한글을 표현하기에는 부족하다.
- 쀏, 뙠, 휔 같이 문자 집합에 정의되지 않는 글자는 표현할 수 없다.
- 이러한 문제를 해결하기 위해 마이크로소프트의 CP949가 등장했지만, 한글 전체를 표현하기에 넉넉한 양은 아니다.
- 인코딩 예시)
- 예시 1) '가'의 경우 b0a0 행의 2번째 열인 b0a1(16)로 인코딩 된다.
- 예시 2) '거'의 경우 b0c0 행의 6번째 열인 b0c5(16)로 인코딩 된다.
이렇게 언어별 인코딩을 나라마다 하게 된다면 다국어를 지원하는 프로그램을 개발해야 할 때엔 언어별 인코딩 방식을 모두 이해해야 하는 번거로움이 존재한다.
예) 영어, 일본어, 중국어, 독일어를 지원하는 웹사이트가 있으면, 4가지 언어의 인코딩 방식을 모두 이해하고 지원해야 한다.
모든 언어, 특수문자까지 통일된 문자 집합을 사용하면 어떨까?
모든 언어를 아우르는 문자 집합과 통일된 표준 인코딩 방식이 있다면?
이에 등장한 것이 바로 유니코드 문자 집합이다.
유니코드와 UTF-8
- 유니코드는 통일된 문자 집합이다.
- 한글, 영어, 화살표와 같은 특수 문자, 이모티콘까지도 코드로 표현할 수 있다.
- 현대 문자를 표현할 때 가장 많이 사용되는 표준 문자 집합으로, 매우 중요한 역할이다.
- 유니코드의 인코딩 방식
- UTF-8, UTF-16, UTF-32 등등
- 유니코드 예시)
- 유니 코드 문자 하나하나에 고유한 십육진수가 부여된 것을 확인할 수 있다.
- 부여된 십육진수가 유니코드의 코드 포인트이다.
- U+: 십육진수로 유니코드를 표현할 때 사용하는 표기이다.
- 부여된 십육진수, 유니코드의 코드 포인트 자체를 인코딩 된 값으로 삼지 않고, 이 값을 다양한 방법으로 인코딩한다
- 유니코드 문자에 부여된 값을 인코딩하는 방식: UTF-8, UTF-16, UTF-32 등등
UTF-8 인코딩
- 가장 대중적이다.
- UTF(Unicode Transformation Format) == 유니코드 인코딩 방법
- 가변 길이 인코딩: 인코딩 결과가 1바이트 ~ 4바이트까지의 인코딩 결과를 만들어 낸다.
- 인코딩한 값의 결과가 1바이트가 될 수도 2바이트, 3바이트, 4바이트가 될 수도 있다.
- 인코딩 결과가 몇 바이트가 될지는 유니코드 문자에 부여된 값(유니코드 코드포인트)의 범위에 따라 결정된다.
- 유니코드 문자에 부여된 값의 범위
- 0부터 007F(16)까지: 1바이트로 표현한다.
- 0080(16)부터 07FF(16)까지: 2바이트로 표현한다.
- 0800(16)부터 FFFF(16)까지: 3바이트로 표현한다.
- 10000(16)부터 10FFFF(16)까지: 4바이트로 표현한다.
- 예시)
- '한글'은 몇 바이트로 구성되는지 알아보자
- '한'에 부여된 값은 D55C(16) == 1101 0101 0101 1100(2)이다.
- '글'에 부여된 값은 AE00(16) == 1010 1110 0000 0000(2)이다.
- 두 글자 모두 0800(16) ~ FFFF(16) 사이에 있다.
- 따라서 '한'과 '글'을 인코딩하면 3바이트로 표현된다.
- 붉은색 X표가 있는 곳에 유니코드 문자에 부여된 고유한 값이 들어간다.
- 예시)
- '한'에 부여된 값을 이진수로 표현하면 1101 0101 0101 1100(2)이다.
- '글'에 부여된 값을 이진수로 표현하면 1010 1110 0000 0000(2)이다.
- UTF-8 방식으로 인코딩을 진행하면 다음과 같은 결과가 나온다.
- '한': 11101101 10010101 10011100(2)
- '글': 11101010 10111000 10000000(2)
참고: 개발을 하다가 글자가 깨지는 경우가 있다. 어떤 것을 의심할 수 있을까?
인코딩이 호환되지 않는지, 문자 집합에 속하지 않는 문자가 사용된 건지를 의심해 보자
'Computer Science > 컴퓨터 구조' 카테고리의 다른 글
[컴퓨터 구조] 메모리와 캐시 메모리 (1) | 2023.04.14 |
---|---|
[컴퓨터 구조] CPU의 성능 향상 기법 (0) | 2023.04.12 |
[컴퓨터 구조] CPU의 작동 원리 (0) | 2023.04.06 |
[컴퓨터 구조] 명령어 (1) | 2023.04.02 |
[컴퓨터 구조] 컴퓨터 구조의 큰 그림 (0) | 2023.03.30 |