진법 변환은 컴퓨터 과학에서 중요한 주제입니다. 이 글에서는 10진수를 2진수, 8진수, 16진수로 변환하는 방법과 그 반대의 과정을 설명하고, 각 진법 간의 상호 변환 방법에 대해서도 다루겠습니다.
16진수 : Hexadecimal(HEX)
10진수 : Decimal(DEC)
8진수 : Octal(OCT)
2진수 : Binary(BIN)
1. 비트 (Bit)
1비트는 컴퓨터의 최소 데이터 단위 입니다. 1비트는 2진수 1자리를 의미합니다(0 또는 1).
컴퓨터의 전기신호에 따라 전기신호가 있으면 true(1) 없으면 false(0)로 나타내기에 컴퓨터는 0과 1로 이루어진 2진수의 수로 데이터를 표현 합니다.
1 비트는 0과 1밖에 없습니다.
2 비트의 데이터는 00, 01, 10, 11로 0과 1이 들어 갈 수 있는 1비트가 2개가 있으니 총 4가지의 데이터가 표현됩니다.
3 비트는 비트가 3자리수이니 000, 001, 010, 011, 100, 101, 110, 111 8개가 되겠군요.
4 비트는 0001, 0010, 0011, 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111의 16가지 데이터로 표현됩니다.
위 규칙을 살펴보면
2 -> 4 -> 8 -> 16 씩 2의 제곱 단위로 가지수가 늘어납니다. 따라서
1비트는 2의 1승 (2^1 = 2)
2비트는 2의 2승 (2^2 = 4)
3비트는 2의 3승 (2^3 = 8)
4비트는 2의 4승 (2^4 = 16) 이 되겠습니다.
2. 바이트(Byte)
바이트(Byte)는 컴퓨터가 데이터를 저장하고 처리하는 기본 단위입니다. 하나의 바이트는 8개의 비트(Bit)로 구성되며, 이진수로 표현됩니다. 각 비트는 0 또는 1의 값을 가질 수 있으며, 8비트가 모여 256개의 서로 다른 값을 표현할 수 있게 됩니다.
1) 비트와 바이트의 관계
- 비트(Bit): 정보의 최소 단위로, 0 또는 1의 값을 가짐.
- 바이트(Byte): 8개의 비트로 구성되며, 하나의 문자를 표현하는 데 사용됨.
- 예를 들어, 0000 0000은 모든 비트가 0인 상태이고, 1111 1111은 모든 비트가 1인 상태입니다.
2) 바이트의 예
- 0000 0000: 이진수로 표현했을 때 최소값이며, 10진수로는 0을 나타냅니다.
- 1001 0000: 10진수로 144에 해당합니다.
- 1111 1111: 모든 비트가 1인 상태로, 10진수 255를 나타냅니다.
3) 바이트의 용도
문자 표현: ASCII나 Unicode 같은 문자 인코딩에서 하나의 바이트로 문자를 나타냅니다. 예를 들어, ASCII에서 0100 0001은 대문자 'A'를 의미합니다.
데이터 전송: 네트워크나 파일 시스템에서 데이터를 전송할 때 바이트 단위로 나눠 전송합니다.
메모리 주소: 컴퓨터 메모리는 바이트 단위로 주소가 지정됩니다.
컴퓨터는 바이트 단위로 데이터를 처리하고, 1바이트는 8비트이므로 다양한 값을 효율적으로 다룰 수 있게 됩니다.
3. 10진수와 2진수
사람이 쓰는 숫자표현은 10진수 입니다. 컴퓨터는 10진수를 이해하지 못해 변환이 필요한데 2byte의 short 타입의 숫자 표현을 예를 들면 아래와 같습니다.
1 -> 00000000 00000001
2 -> 00000000 00000010
3 -> 00000000 00000011
4 -> 00000000 00000100
4. 10진수를 2진수, 8진수, 16진수로 변환하기
정수 부분 변환
10진수의 정수 부분을 다른 진수로 변환하는 방법은 다음과 같습니다:
- 변환할 진수로 10진수 값을 나눕니다.
- 몫과 나머지를 기록합니다.
- 몫이 0이 될 때까지 나누기를 반복합니다.
- 나머지를 역순으로 읽습니다.
소수 부분 변환
10진수의 소수 부분을 변환하는 방법은 다음과 같습니다:
- 소수 부분에 변환할 진수를 곱합니다.
- 결과의 정수 부분을 기록합니다.
- 소수 부분이 0이 되거나 반복되는 수가 나올 때까지 위 과정을 반복합니다.
예: 47.625를 2진수, 8진수, 16진수로 변환하기
2진수로 변환
정수 부분:
2 | 47
2 | 23 ... 1
2 | 11 ... 1
2 | 5 ... 1
2 | 2 ... 1
1 ... 0
=> (47)10 = (101111)2
소수 부분:
0.625 * 2 = 1.25 -> 1
0.25 * 2 = 0.5 -> 0
0.5 * 2 = 1.0 -> 1
=> (0.625)10 = (0.101)2
최종 변환:
(47.625)10 = (101111.101)2
8진수로 변환
정수 부분:
8 | 47
5 ... 7
=> (47)10 = (57)8
소수 부분:
0.625 * 8 = 5.000
=> (0.625)10 = (0.5)8
최종 변환:
(47.625)10 = (57.5)8
16진수로 변환
정수 부분:
16 | 47
2 ... 15(F)
=> (47)10 = (2F)16
소수 부분:
0.625 * 16 = 10(A).000
=> (0.625)10 = (0.A)16
최종 변환:
(47.625)10 = (2F.A)16
5. 다른 진법을 10진수로 변환하기
2진수, 8진수, 16진수를 10진수로 변환하는 방법:
- 각 자리의 숫자를 해당 진수의 자리 값으로 곱합니다.
- 모든 결과를 더합니다.
예: (101111.101)2를 10진수로 변환하기
(1 0 1 1 1 1 . 1 0 1)2
= 2^5 + 2^3 + 2^2 + 2^1 + 2^0 + 2^-1 + 2^-3
= 32 + 8 + 4 + 2 + 1 + 0.5 + 0.125
= 47.625
예: (57.5)8를 10진수로 변환하기
(5 7 . 5)8
= 5 * 8^1 + 7 * 8^0 + 5 * 8^-1
= 40 + 7 + 0.625
= 47.625
예: (2F.A)16을 10진수로 변환하기
(2 F . A)16
= 2 * 16^1 + 15 * 16^0 + 10 * 16^-1
= 32 + 15 + 0.625
= 47.625
6. 진법 간 상호 변환
2진수를 8진수로 변환
정수 부분은 소수점을 기준으로 왼쪽으로 3자리씩, 소수 부분은 오른쪽으로 3자리씩 묶어서 변환합니다.
예: (111001011.10101)2를 8진수로 변환하기
111 001 011 . 101 010
(7 1 3 . 5 2)8
=> (111001011.10101)2 = (713.52)8
2진수를 16진수로 변환
정수 부분은 소수점을 기준으로 왼쪽으로 4자리씩, 소수 부분은 오른쪽으로 4자리씩 묶어서 변환합니다.
예: (11001011.10101)2를 16진수로 변환하기
1100 1011 . 1010 1000
(C B . A 8)16
=> (11001011.10101)2 = (CB.A8)16
8진수를 2진수로 변환
8진수 1자리는 2진수 3자리로 변환합니다.
예: (713.52)8를 2진수로 변환하기
7 -> 111, 1 -> 001, 3 -> 011, . 5 -> 101, 2 -> 010
=> (713.52)8 = (111001011.10101)2
16진수를 2진수로 변환
16진수 1자리는 2진수 4자리로 변환합니다.
예: (1B8.6A8)16를 2진수로 변환하기
1 -> 0001, B -> 1011, 8 -> 1000, . 6 -> 0110, A -> 1010, 8 -> 1000
=> (1B8.6A8)16 = (11011000.01101010)2
7. 8진수와 16진수 간의 변환
8진수를 16진수로 변환하기
8진수를 먼저 2진수로 변환한 뒤 16진수로 변환합니다.
예: (670.325)8을 16진수로 변환하기
- 8진수를 2진수로 변환:
6 -> 110, 7 -> 111, 0 -> 000, . 3 -> 011, 2 -> 010, 5 -> 101
=> (670.325)8 = (110111000.011010101)2
- 2진수를 16진수로 변환:
1 1011 1000 . 0110 1010 1000
=> (110111000.011010101)2 = (1B8.6A8)16
8. 보수
-의 값을 표현하려 왼쪽 마지막 비트를 +,-의 구분으로 사용합니다.
예를 들어 2byte의 short형으로 아래와 같이 값이 표현 되었다면 10진수로 어떤 값일까요?
11111111 11111111
65,535 일까요? 정답은 -1 입니다. 왼쪽 마지막 비트를 +와 -를 구분짓는데 사용합니다.
2byte의 short에서 가장 큰값은
01111111 11111111 의 값인 32,767 입니다. 그래서 short의 값의 범위가 -32,768 ~ 32,767 입니다.
만약 맨앞자리를 +, -를 구분짓는데 사용않하겠다면 unsigned short을 사용하면 됩니다.
그럼 부호비트까지 사용할수 있습니다.
11111111 11111111 값이 65,535이 되고 값의 범위는 0 ~ 65,535로 사용할수 있습니다.
5. 3을 -3으로 표현하는법
1. 0000 0011값을 반전시킵니다.
2. 1111 1100 반전시킨 값에 1을 더합니다.
3. 1111 1101 이 -3이 됩니다.
이와 같이 -5를 만드는법은
0000 0101 값을 반전시키고
1111 1010 반전시킨 값에 1을 더하면
1111 1011 이 -5가 됩니다.
9. 데이터 손실과 케스팅
#include <iostream>
using namespace std;
int main()
{
int maxHp = INT_MAX;
cout << "maxHp : " << maxHp << endl;
maxHp++;
cout << "maxHp : " << maxHp << endl;
// 다운 케스팅
int maxMp = INT_MAX;
//short mp = (short)maxMp; // 케스팅이 생략된 형태
short mp = maxMp; // 오버플로우 발생
/************ 데이터 손실 발생(DownCasting)
int maxMp : 01111111 11111111 11111111 11111111 -> 2,147,483,647
short mp : 11111111 11111111 -> -1
*/
// 업 케스팅
int maxAttack = INT_MAX;
short attack = SHRT_MAX;
//maxAttack = (int)attack; // 케스팅이 생략된 형태
maxAttack = attack;
cout << "maxAttack : " << maxAttack << endl;
/************ 데이터 보존(UpCasting)
short attack : 01111111 11111111 -> 32,767
int maxAttack : 00000000 00000000 01111111 11111111 -> 32,767
*/
}
10. 진수 체계별 숫자 표기법 정리
숫자를 표현할 때 각 진수 체계에 따라 사용하는 접두사를 정리했습니다. 이를 통해 숫자를 명확하게 표현하고 해석할 수 있습니다.
1) 2진수 (Binary)
2진수는 컴퓨터에서 데이터와 명령어를 처리하는 기본 단위입니다. 2진수는 0과 1만을 사용합니다.
- 접두사: 0b
- 예시:
- 0b1000000001 (십진수로 513)
2) 8진수 (Octal)
8진수는 0부터 7까지의 숫자를 사용합니다. 주로 컴퓨터 과학과 디지털 전자공학에서 사용됩니다.
- 접두사: 0o
- 예시:
- 0o1001 (십진수로 513)
3) 10진수 (Decimal)
10진수는 일상생활에서 가장 많이 사용하는 숫자 체계로, 0부터 9까지의 숫자를 사용합니다.
- 접두사: 없음
- 예시:
- 513
4) 16진수 (Hexadecimal)
16진수는 0부터 9까지의 숫자와 A부터 F까지의 알파벳을 사용합니다. 주로 컴퓨터 과학에서 색상 코드나 메모리 주소 등을 표현할 때 사용됩니다.
- 접두사: 0x
- 예시:
- 0x0201 (십진수로 513)
요약
진수 체계사용 숫자접두사예시
2진수 | 0, 1 | 0b | 0b1000000001 |
8진수 | 0-7 | 0o | 0o1001 |
10진수 | 0-9 | 없음 | 513 |
16진수 | 0-9, A-F | 0x | 0x0201 |
이 표기법들을 사용하여 숫자를 다양한 진수 체계로 명확하게 표현할 수 있습니다.