Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 언어로 16진수를 8진수로 변환하는 프로그램

개요

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진수 값을 반환합니다.

알고리즘

  1. hexa_binary(char hex[]) : 16진수 문자열을 받아 2진수(long long int)로 변환해 반환합니다. 문자열의 각 문자를 switch 문으로 검사하여 '0'~'9'와 'a'~'f'(대소문자 모두 지원)에 맞는 4비트 2진수 값을 더하고, place = 10000으로 자릿수를 이어 줍니다. 잘못된 입력이 들어오면 오류 메시지를 출력합니다.
  2. binary_oct(long long binary) : 2진수를 세 자리 단위(% 1000)로 잘라 각 그룹을 0~7 사이의 8진수 값으로 바꾸고, place(1, 10, 100...)를 곱해 자릿수를 맞춘 뒤 누적합니다. 매 반복마다 binary /= 1000, place *= 10을 수행합니다.
  3. hexa_oct(char hex[]) : hexa_binary()로 16진수 → 2진수 변환을 수행한 뒤, binary_oct()로 2진수 → 8진수 변환을 수행해 최종 결과를 반환합니다.
  4. 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입니다.