컴퓨터공학

[하드웨어] 2진수와 컴퓨터

nvvs 2022. 8. 23. 17:55
해당 포스팅은 아래 서적을 요약한 것입니다.
「초보프로그래머가 꼭 알아야할 컴퓨터 동작 원리」, 김종훈, 한빛미디어(주)

 

Intro

왜 컴퓨터는 우리에게 친숙한 10진수 대신 2진수를 사용할까요?

초기의 컴퓨터인 에니악(ENIAC)은 10진수를 사용했습니다. 하지만 연산상 문제로 인한 고열 발생, 연산 처리 능력 저하, 컴퓨터의 부피 증가 등의 문제점 때문에 다른 방법을 모색하게 되었습니다.

컴퓨터는 on/off로 동작하는 전기 신호의 조합입니다. 이런 컴퓨터 내의 정보를 표현하는데 2진수를 딱 맞는 구조였습니다.

표현하는 단계가 적은 만큼 잡음에도 강하고 처리속도도 빨라 이후의 컴퓨터부터는 2진수를 사용하게 되었습니다.

하지만 프로그래밍을 할 때는 2진수는 너무 길었습니다. 그래서 사용하기 시작한 것이 2진수를 함축적으로 표현할 수 있으면서 기계적으로 변환이 가능한 8진수와 16진수입니다.

컴퓨터의 하드웨어와 운영체제 및 응용 프로그램에서 데이터 표현은 다릅니다.

응용 프로그램은 10진수, 문자로 표현하고, 운영체제는 8진수, 16진수, 하드웨어는 2진수로 데이터를 표현합니다.

아래의 내용을 통해 더 자세하게 하드웨어가 2진수로 작동하는 원리를 알아보도록 하겠습니다.

 

왜 2진수로 표현할까

컴퓨터를 구성하는 집적회로(IC)는 2진수 형태로 동작합니다.

집적회로 (IC, integrated circuit)
집적회로 (IC, integrated circuit)

집적회로는 트랜지스터, 다이오드, 저항, 축전기 등을 하나의 작은 실리콘 기판 위에 형성하고 이를 배선하여 만들어진 소자를 말합니다.

예) CPU, 메모리 등

 

집적회로는 on/off의 형식으로 동작합니다. 전압을 가하면 on, 전압을 가하지 않으면 off입니다.

on은 1을 의미, off는 0을 의미하도록 하여 2진수로 표현합니다. 즉, 집적회로는 on/off 즉, 1과 0의 2진수 개념을 갖게 되는 것입니다.

이에 따라 컴퓨터 내부에서는 정보를 10진수나 문자가 아닌 2진수로 표현합니다.

 

2진 정보를 구성하는 최소단위는 비트(bit, binary digit)입니다. 비트 8개가 모여 최소한의 의미를 지니는 단위는 바이트(byte)입니다.

▣ 비트 = 1 또는 0
▣ 바이트 = 8비트

 

1바이트로 표현할 수 없는 정보는 2바이트 또는 4바이트와 같이 묶어서 표현합니다.

예) 'a'는 1바이트(8비트)로 표현

      'a' = 01100001 (하나의 1 또는 0은 비트, 비트가 8개 모여서 1바이트)

 

진법과 진수

1. 진법과 진수란

진법은 숫자의 위치에 따라 가중치가 달라지는 수로 나타내는 방법을 말합니다. 진수는 그 수를 뜻합니다.

10진수: 0~9까지 10개의 숫자를 사용, 한 자리 위의 값이 10배
☞ 10진수 349의 각 자리의 숫자는 300, 40, 9
☞ 349 = 3*10² + 4*10¹ + 9

 

컴퓨터에서는 2진수, 8진수, 16진수를 주로 사용합니다. 

2진수는 한 자리 위의 숫자가 2배입니다. 0~1까지의 숫자를 사용합니다.

8진수는 한 자리 위의 숫자가 8배입니다. 0~7까지의 숫자를 사용합니다.

16진수는 한 자리 위의 숫자가 16배입니다. 0~9까지의 숫자를 사용하며, 10~15를 의미하는 A~F를 사용합니다.

해당 진수는 맨 우측 아래 첨자로 표시합니다.

1101₂     567₈      A1₁₆

 

2진수, 8진수, 16진수의 각 자리 숫자에 가중치를 곱해 더하면 10진수가 됩니다.

1011₂ = 1*2³ + 0*2² + 1*2¹ + 1
567₈ = 5*8² + 6*8¹ + 7
A1₁₆ = 10(A)*16¹ + 1

 

2. 진수 변환하기

진수 변환 형태는 아래와 같습니다.

X진수 ↔ 10진수
2진수 ↔  2ⁿ(4, 8, 16)진수
X진수 → P진수

 

X진수 ↔ 10진수

먼저 X진수 → 10진수(X진수의 10진수로의 변환)을 알아보겠습니다.

7진수를 10진수로 변환하려면 각 자리 숫자에 가중치를 곱해 더합니다.

352.6₇ = 3*7² + 5*7¹ + 2*7⁰ + 6*7⁻¹
            = 147 + 35 + 2 +  6/7
            = 184.857₁₀ 

 

10진수 → X진수(10진수의 X진수로의 변환)은 정수부의 경우 X진수의 X로 나눠 나머지를 역순으로 나열하여 변환합니다. 소수부의 경우 X진수의 X를 곱해 그 결과의 소수점 윗자리를 위에서 아래로 읽어 변환합니다.

10진수 37.6875를 2진수로 변환해 봅시다.

37.6875의 정수부 37을 2로 계속 나누면 정수부의 2진수 값이 나오게 됩니다.

37/2 = 18 ··· 1
18/2 =  9  ··· 0
 9/2  =  4  ··· 1
 4/2  =  2  ··· 0
 2/2  =  1  ··· 0   

 ∴ 100101

 

37.6875의 소수부 0.6875에 2를 곱하고 그 결과의 소수점 윗자리를 위에서 아래로 읽으면 2진수 값이 나오게 됩니다.

이때 나눈 결과값을 다시 나눌때는 소수점 윗자리를 0으로 바꿔 진행하여야 합니다.

0.6875 * 2 = 1.3750 ☞ 0.1
0.3750 * 2 = 0.7500 ☞ 0.10
0.7500 * 2 = 1.5000 ☞ 0.101
0.5000 * 2 = 1.0000 ☞ 0.1011 

 0.1011

 

위의 과정을 거쳐 10진수 37.6875는 2진수로 100101.1011로 변환됩니다.

 

10진수 524.76을 16진수로 변환해 봅시다.

524.76의 정수부 524를 16으로 계속 나눠 나머지를 역순으로 나열하면 16진수 값이 나오게 됩니다.

524/16 = 32 ··· 12(C)
  32/16 =   2 ··· 0

 20C

 

524.76의 소수부 0.76에 16을 곱하고 그 결과의 소수점 윗자리를 위에서 아래로 읽으면 16진수 값이 나오게 됩니다.

이때 나눈 결과값을 다시 나눌때는 소수점 윗자리를 0으로 바꿔 진행하여야 합니다.

0.76 * 16 = 12.16 ☞ 0.C(12)
0.16 * 16 =   2.56 ☞ 0.C2
0.56 * 16 =   8.96 ☞ 0.C28

0.C28

 

위의 과정을 거쳐 10진수 524.76은 16진수로 20C.C28로 변환됩니다.

 

2진수 ↔  2ⁿ(4, 8, 16)진수

2진수를 4, 8, 16같은 2ⁿ 진수로 변환(2진수 →  2ⁿ(4, 8, 16)진수)하는 방법을 알아보겠습니다.

2진수 2비트는 4진수의 한자리에 대응됩니다.

2진수 3비트는 8진수의 한 자리에 대응됩니다.

2진수 4비트는 16비트 한 자리에 대응됩니다.

위의 원리를 이용하여 대응하는 비트씩 묶어 각 묶음을 해당하는 진수로 바꾸면 됩니다. 이때 묶음으로 묶어지지 않고 하나만 남은 경우에도 대응하는 자리로 묶어 변환해야 합니다.

 

2진수를 4진수로 바꿀때는 2진수의 2비트가 4진수의 한 자리에 대응하기 때문에 2비트씩 묶어 각 묶음을 4진수로 바꾸면 됩니다. 소수점을 기준으로 2비트씩 묶으면 됩니다.

2진수 10110.111010을 4진수로 변환해보겠습니다.

 

2진수 00 01 10 11
4진수 0 1 2 3
0 1 0 1 1 0 . 1 1 1 0 1 0
 1    1    2   .  3     2    2

10110.11101₂ ☞ 112.322₄

 

정수부는 뒤에서부터 2비트씩 묶어 계산해야 하므로 가장 첫번째 자리는 한 비트만 남습니다. 이에 0을 추가하여 두자리로 '01' 만들어 계산합니다. 소수부는 앞에서부터 2비트씩 묶어 계산합니다. 마찬가지로 마지막 자리는 한 비트만 남아 0을 추가하여 '10'으로 만들어 계산합니다.

 

같은 원리로 8진수는 2진수의 3비트가 8진수의 한 자리에 대응합니다. 

2진수 10110.11101을 8진수로 변환하면 아래와 같습니다.

 

2진수 000 001 010 011 100 101 110 111
8진수 0 1 2 3 4 5 6 7
0 1 0 1 1 0 . 1 1 1 0 1 0 
   2       6    .    7       2

10110.11101₂ ☞ 26.72

 

16진수는 2진수의 4비트가 16진수의 한 자리에 대응합니다.

2진수 10110.11101을 16진수로 변환하면 아래와 같습니다.

 

2진수 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001
16진수 0 1 2 3 4 5 6 7 8 9
2진수 1010 1011 1100 1101 1110 1111
16진수 A B C D E F
0 0 0 1 0 1 1 0 . 1 1 1 0 1 0 0 0
    1          6      .      E          8

10110.11101₂ ☞ 16.E8

 

2ⁿ진수를 2진수로의 변환(2ⁿ(4, 8, 16)진수 → 2진수)은 위의 방법을 반대로 합니다.

4진수의 한 자리가 2진수의 2비트이고, 8진수의 한 자리가 2진수의 3비트이며, 16진수의 한 자리가 2진수의 4비트임을 적용하여 변환합니다.

   A         1      .      6   
1010   0001   .   0110

A1.6₁₆ ☞ 10100001.0110₂

 

③ X진수 → P진수

10진수를 제외한 X진수를 P진수로 바로 변환할 수 있는 방법은 알려지지 않았습니다. 따라서 X진수를 먼저 10진수로 바꾸고, P진수로 다시 바꿔야 합니다.

2진수를 7진수로 변환하는 방법은 아래와 같습니다.

1011101₂ → 93 → 162₇

 

컴퓨터에서 문자, 숫자 표현

1. 컴퓨터에서 문자 표현하기

 

2. 컴퓨터에서 정수 표현하기

현실 공간에서는 정수를 제한 없이 적을 수 있습니다.

483
4567123558745335687612355

하지만 컴퓨터의 기억공간은 제한적이기 때문에 한 정수를 나타낼 기억 영역도 제한적일 수 밖에 없습니다.

정수 하나는 2바이트 또는 4바이트로 표현합니다. 즉, 2바이트 또는 4바이트가 정수 하나의 저장 영역입니다.

이렇게 정수를 저장하는 영역의 크기가 정해져 있기 때문에 표현 가능한 정수의 범위 역시 제한적입니다.

▣ 2바이트(16비트)로 표현할 수 있는 최대값 = 2¹⁶-1 = 65,535
▣ 4바이트(32비트)로 표현할 수 있는 최대값 = 2³²-1 = 4,294,967,295


컴퓨터에서 정수의 음수를 나타내는 방법은 두 가지가 있습니다. 부호절대값(signed- magnitude)과 2의 보수(2's complement) 입니다.

부호절대값은 부호를 저장하는 비트를 별도로 두는 표현법입니다. 가장 좌측에 있는 비트가 부호비트로 양수면 0, 음수면 1로 표시합니다.

예를 들어 양의 정수 45는 양수를 뜻하는 0이 부호비트 자리에 들어가고 나머지 자리에는 45를 2진수로 변환한 값이 들어갑니다. 음의 정수 -45는 부호비트에 1이 들어갑니다.

▣  45: 0[부호비트]000000000[나머지 비트는 0으로 채움]101101[45의 2진수 101101]
-45: 1[부호비트]000000000[나머지 비트는 0으로 채움]101101[45의 2진수 101101]

 

부호절대값은 부호비트로 한 자리가 빠지기 때문에 2바이트의 부호절대값으로 표현할 수 있는 값의 범위는 -(2¹⁵-1) ~ 2¹⁵-1, -32,767 ~ 32,767이 됩니다.

하지만 부호절대값 표현은 사용하지 않는 -0을 표현하는 문제, 연산의 불편함으로 사라졌습니다.

 

현재는 2의 보수 표현을 사용합니다. 2의 보수 표현은 양수를 표현하는 방법은 부호절대값 표현과 동일하지만, 음수 표현방식이 다릅니다. 음수를 표현할 때 2진수로 변환한 수에서 0은 1로, 1은 0으로 변경한 뒤 1을 더하는 방식입니다.

-45를 2의 보수 표현을 통해 나타내 보겠습니다.

1. -45를 2진수로 변경
 ☞ 0000000000101101
2. 0은 1로, 1은 0으로 변경
 ☞ 1111111111010010
3. 1을 더함
 ☞1111111111010011

 

가장 좌측 비트가 1이 됨을 확인할 수 있습니다. 2바이트의 2의 보수 방식으로 표현할 수 있는 값의 범위는 -2¹ ~ 2¹⁵-1, -32,768 ~ 32,767이 됩니다. -0을 표현하지 않기 때문에 -32,768을 더 표현할 수 있고, 연산이 매우 효율적입니다.

▣ n비트로 표현할 수 있는 수의 범위
 - 부호절대값 표현 : - (2ⁿ⁻¹ -1) ~ 2ⁿ⁻¹ -1
 - 2의 보수 표현: - 2ⁿ⁻¹ ~ 2ⁿ⁻¹ -1

 

3. 컴퓨터에서 실수 표현하기

실수도 컴퓨터 내부에서는 제한된 공간에 2진수 형태로 표현됩니다. 컴퓨터 내부에서 실수를 표현할 때는 지수형식을 이용해서 4바이트나 8바이트로 표현합니다.

▣ 지수형식
m * rⁿ ☞ m: 가수 / r: 밑수 / n: 지수
예) 0.8 * 10⁻¹

 

실수를 정의하는 형식은 두 가지가 있습니다. IEEE754 표준으로 단일정밀도 형식과 이중정밀도 형식입니다.

단일정밀도 형식은 8비트 지수의 4바이트 형식이고, 이중 정밀도 형식은 11비트 지수의 8바이트 형식입니다.

밑수는 2로 정해져있기 때문에 표시하지 않습니다.

 

단일정밀도 형식 [8비트 지수의 4바이트(32비트) 형식]

이중정밀도 형식 [11비트 지수의 8바이트(64비트) 형식]

단일정밀도 형식으로 컴퓨터에서 실수 -0.001101₂ * 2²을 표현하는 과정을 알아봅시다.

첫번째로 가수가 ±1.???₂ * 2ⁿ 형식이 되도록 변환합니다. 가수를 왼쪽으로 세자리 이동시키고 지수를 3 감소시키면 됩니다. 이와 같은 과정을 "정규화 시킨다."라고 합니다.

▣ ±1.???₂ * 2ⁿ 형식이 되도록 변환
가수를 왼쪽으로 세자리 이동 ☞ -1.101₂ * 2²
지수를 3 감소 ☞ -1.101₂ * 2⁻¹


다음으로 8비트로 표현되는 지수를 바이어스 된 표현법으로 변환합니다. 실제 지수에 고정값(바이어스)을 더하면 바이어스 된 지수를 구할 수 있습니다. 지수를 바이어스 된 지수로 표현하는 이유는 음의 지수를 나타내기 위함입니다.

지수 + 바이어스 = 바이어스 된 지수
※ IEEE754 표준에서 바이어스 값은 127입니다.
현재 지수 = -1
바이어스 값 = 127
-1 + 127 = 126

-1.101₂ * 2¹²

 

4바이트(32비트) 2진수 형태로 표현합니다.

1 [음수인 가수의 부호 (-)]
01111110 [바이어스 된 지수 126을 8비트로 표현]
101 [가수 1.101의 소수점 아래인 101을 표현]
00000000000000000000 [나머지 가수를 0으로 채움]

∴ -0.001101₂ * 2² ☞ 10111111010100000000000000000000

 

위 과정을 지나 컴퓨터에서 실수 -0.001101₂ * 2²은 10111111010100000000000000000000로 표현됩니다.