개요
16진수(Hexadecimal) 숫자가 문자열 형태로 주어졌을 때, 이를 8진수(Octal)로 변환하는 것이 목표입니다. 16진수를 8진수로 바로 변환하기는 어렵기 때문에, 일반적으로 다음의 두 단계를 거칩니다.
- 16진수에 해당하는 2진수 값을 구합니다.
- 구한 2진수를 8진수로 변환합니다.
16진수란 무엇인가?
16진수는 밑(base)이 16인 수 체계입니다. 0~9까지는 숫자를 그대로 사용하고, 10부터는 알파벳으로 표현합니다. 즉, A는 10, B는 11, C는 12, D는 13, E는 14, F는 15를 의미합니다.
16진수를 2진수로 변환할 때는 각 자리의 숫자나 문자를 4비트짜리 2진수 값으로 바꾼 뒤, 이들을 모두 이어 붙여 하나의 2진수를 만듭니다.
8진수란 무엇인가?
8진수는 컴퓨터에서 밑이 8인 수 체계로, 0부터 7까지의 숫자로 표현됩니다. 8진수는 2진수 세 자리(3비트)씩 묶어서 만들 수 있습니다.
변환 과정 살펴보기
예를 들어 16진수 1A6가 주어졌다고 가정해 보겠습니다. 이 값은 각각 1, 10(A), 6을 의미합니다. 16진수를 8진수로 변환하려면 먼저 2진수 값을 구해야 합니다.
- 1 → 0001
- A(10) → 1010
- 6 → 0110
따라서 1A6의 2진수 표현은 0001 1010 0110입니다.
다음으로 이 2진수를 8진수로 변환해야 합니다. 변환 전에 2진수를 세 자리씩 묶으면 000 110 100 110이 되고, 각 그룹의 8진수 값은 다음과 같습니다.
- 000 → 0
- 110 → 6
- 100 → 4
- 110 → 6
따라서 16진수 1A6의 8진수 표현은 646입니다.
입출력 예시
입력: 1A6 출력: Octal Value = 646 입력: 1AA 출력: Octal Value = 652
문제 해결 접근 방법
- 입력값을 받아 문자열로 저장합니다.
- 다음 방식으로 16진수를 2진수로 변환합니다.
- 16진수의 16가지 경우(0~9, A~F)마다 대응되는 2진수 표현을 차례로 더합니다.
- 완성된 2진수를 반환합니다.
- 다음 단계에 따라 2진수를 8진수로 변환합니다.
- 2진수를 세 자리씩 나누어 가능한 모든 경우(000~111)를 8진수 값에 대응시킵니다.
- octal = (val × place) + octal 식으로 자릿값을 누적합니다.
- 2진수를 1000으로 나누어 다음 그룹으로 이동합니다.
- place *= 10으로 자릿값을 한 자리씩 올립니다.
- 최종 8진수 값을 반환합니다.
알고리즘
- hexa_binary(char hex[]) : 16진수 문자열을 받아 2진수(long long int)로 변환해 반환합니다. 문자열의 각 문자를 switch 문으로 검사하여 '0'~'9'와 'a'~'f'(대소문자 모두 지원)에 맞는 4비트 2진수 값을 더하고, place = 10000으로 자릿수를 이어 줍니다. 잘못된 입력이 들어오면 오류 메시지를 출력합니다.
- binary_oct(long long binary) : 2진수를 세 자리 단위(% 1000)로 잘라 각 그룹을 0~7 사이의 8진수 값으로 바꾸고, place(1, 10, 100...)를 곱해 자릿수를 맞춘 뒤 누적합니다. 매 반복마다 binary /= 1000, place *= 10을 수행합니다.
- hexa_oct(char hex[]) : hexa_binary()로 16진수 → 2진수 변환을 수행한 뒤, binary_oct()로 2진수 → 8진수 변환을 수행해 최종 결과를 반환합니다.
- main() : 예제 16진수 문자열("5CD")을 설정하고 hexa_oct()를 호출하여 결과를 출력합니다.
C 프로그램 전체 소스 코드
#include <stdio.h>
#include <string.h>
#include <math.h>
// 16진수를 먼저 2진수로 변환하는 함수
long long int hexa_binary(char hex[]) {
long long int binary, place;
int i = 0, rem, val;
int n = strlen(hex);
binary = 0ll;
place = 0ll;
for (i = 0; hex[i] != '\0'; i++) {
binary = binary * place;
switch (hex[i]) {
case '0':
binary += 0;
break;
case '1':
binary += 1;
break;
case '2':
binary += 10;
break;
case '3':
binary += 11;
break;
case '4':
binary += 100;
break;
case '5':
binary += 101;
break;
case '6':
binary += 110;
break;
case '7':
binary += 111;
break;
case '8':
binary += 1000;
break;
case '9':
binary += 1001;
break;
case 'a':
case 'A':
binary += 1010;
break;
case 'b':
case 'B':
binary += 1011;
break;
case 'c':
case 'C':
binary += 1100;
break;
case 'd':
case 'D':
binary += 1101;
break;
case 'e':
case 'E':
binary += 1110;
break;
case 'f':
case 'F':
binary += 1111;
break;
default:
printf("Invalid hexadecimal input.");
}
place = 10000;
}
return binary;
}
// 2진수를 8진수로 변환하는 함수
long long int binary_oct(long long binary) {
long long int octal, place;
int i = 0, rem, val;
octal = 0ll;
place = 1;
// 8진수 변환을 위한 모든 2진수 조합 처리
while (binary > 0) {
rem = binary % 1000;
switch (rem) {
case 0:
val = 0;
break;
case 1:
val = 1;
break;
case 10:
val = 2;
break;
case 11:
val = 3;
break;
case 100:
val = 4;
break;
case 101:
val = 5;
break;
case 110:
val = 6;
break;
case 111:
val = 7;
break;
}
octal = (val * place) + octal;
binary /= 1000;
place *= 10;
}
return octal;
}
// 16진수를 8진수로 변환하는 함수
long long int hexa_oct(char hex[]) {
long long int octal, binary;
// 16진수 → 2진수 변환
binary = hexa_binary(hex);
// 2진수 → 8진수 변환
octal = binary_oct(binary);
return octal;
}
// 메인 함수
int main() {
char hex[20] = "5CD";
printf("Octal Value = %lld", hexa_oct(hex));
return 0;
}
실행 결과
Octal Value = 2715
결과 확인: 16진수 5CD는 2진수로 0101 1100 1101이며, 이를 세 자리씩 묶으면 010 111 001 101이 됩니다. 각 그룹을 8진수로 바꾸면 2, 7, 1, 5가 되어 최종 결과는 2715입니다.