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

C++ 진법 변환 완벽 가이드: 임의의 진법 ↔ 10진수 상호 변환

이 튜토리얼에서는 C 스타일의 C++ 코드를 사용하여 임의의 진법의 수를 10진수로 변환하는 방법과, 그 반대로 10진수를 원하는 진법으로 변환하는 방법을 예제와 함께 살펴봅니다.

진법 변환은 2진수, 8진수, 16진수 등 다양한 진법의 수를 다룰 때 반드시 이해해야 하는 기본 개념입니다. 여기서는 정수와 그 수의 진법이 주어졌을 때 해당 수의 10진수 등가값을 구하는 프로그램을 작성하고, 이어서 그 역연산도 함께 구현해 보겠습니다.

1. 임의의 진법 → 10진수 변환

진법 변환의 원리는 간단합니다. 문자열의 각 자릿값을 구한 뒤, 가장 오른쪽 자릿수부터 진법의 거듭제곱(1, base, base², …)을 곱해 모두 더하면 10진수 값이 됩니다.

예를 들어 16진수 "11A"의 경우 (1×16²) + (1×16¹) + (10×16⁰) = 256 + 16 + 10 = 282가 됩니다.

#include <stdio.h>
#include <string.h>

// 문자의 값을 반환하는 함수
int val(char c) {
if (c >= '0' && c <= '9')
return (int)c - '0';
else
return (int)c - 'A' + 10;
}

// 주어진 진법의 수를 10진수 등가값으로 변환
int convert_decimal(char *str, int base) {
int len = strlen(str);
int power = 1; // 진법의 거듭제곱
int num = 0; // 결과값
int i;
for (i = len - 1; i >= 0; i--) {
// 각 자릿값이 진법보다 크면 잘못된 입력
if (val(str[i]) >= base) {
printf("Invalid Number");
return -1;
}
num += val(str[i]) * power;
power = power * base;
}
return num;
}

int main() {
char str[] = "11A";
int base = 16;
printf("Decimal equivalent of %s in base %d is %d\n", str, base, convert_decimal(str, base));
return 0;
}

출력

Decimal equivalent of 11A in base 16 is 282

위 코드에서 val() 함수는 문자를 해당 숫자 값으로 바꿔 줍니다. '0'~'9'는 그대로 0~9로, 'A' 이상의 문자는 10 이상의 값으로 변환합니다. 변환 과정에서 자릿값이 진법 이상이면 유효하지 않은 수로 판단하여 -1을 반환합니다.

2. 10진수 → 임의의 진법 변환

이번에는 반대 연산을 수행해 보겠습니다. 10진수를 원하는 진법으로 변환할 때는 해당 진법으로 계속 나누면서 나머지를 기록하고, 마지막에 나머지들을 역순으로 이어 붙이면 됩니다.

예를 들어 282를 16진수로 바꾸면 282 ÷ 16 = 17 … 10(A), 17 ÷ 16 = 1 … 1, 1 ÷ 16 = 0 … 1이므로, 나머지를 역순으로 읽어 "11A"가 됩니다.

#include <stdio.h>
#include <string.h>

// 숫자 값을 대응하는 문자로 반환하는 함수
char reVal(int num) {
if (num >= 0 && num <= 9)
return (char)(num + '0');
else
return (char)(num - 10 + 'A');
}

// 주어진 문자열을 뒤집는 함수
void reverse_string(char *str) {
int len = strlen(str);
int i;
for (i = 0; i < len / 2; i++) {
char temp = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = temp;
}
}

// 10진수를 진법 'b'의 등가 수로 변환
char* convert_base(char res[], int base, int inputNum) {
int index = 0;
while (inputNum > 0) {
res[index++] = reVal(inputNum % base); // 나머지를 문자로 저장
inputNum /= base;
}
res[index] = '\0';
reverse_string(res); // 나머지를 역순으로 뒤집기
return res;
}

int main() {
int inputNum = 282, base = 16;
char res[100];
printf("Equivalent of %d in base %d is %s\n", inputNum, base, convert_base(res, base, inputNum));
return 0;
}

출력

Equivalent of 282 in base 16 is 11A

정리

두 변환 과정을 요약하면 다음과 같습니다.

  • 진법 → 10진수: 각 자릿수 값에 진법의 거듭제곱을 곱하여 모두 더합니다.
  • 10진수 → 진법: 10진수를 목표 진법으로 반복해서 나누고, 나머지를 역순으로 배열합니다.

이 두 함수를 하나의 프로그램에 함께 두면 10진수를 경유하여 임의의 진법 사이를 자유롭게 변환할 수 있으며, 시간 복잡도는 입력 자릿수에 비례하는 O(n)으로 매우 효율적입니다.