진법 (Number System)

  • 진법이란, 수를 세는 방법 또는 단위
  • r진법이란 0, 1, …, (r-1)까지의 숫자만을 사용해서 수를 표현한 것
  • 각 위치에 따른 서로 다른 가중치(자릿값)가 존재
    • 10진법으로 표현된 “123”의 경우 100 * 10^2 + 2 * 10^1 + 3 * 10^0

예컨대, 2진법은 0과 1만을 사용해 수를 표현한 것이며 8진법은 0에서 7까지의 숫자만을 사용해 수를 표현한 것이다. 16진법처럼 10을 넘어가는 수의 경우에는 10 이상의 숫자를 각각 A, B, …, F의 알파벳에 대응해 표현한 것이다.

진법의 변환

n진수를 10진수로 변환하는 경우

  • 각 값 * 해당 위치의 가중치의 합이 해당 n진법의 10진수값이 된다
    • 2진법으로 표현된 “101.101”의 경우 1 * 2^2 + 0 * 2^1 + 1 * 2^0 + 1 * 2^(-1) + 0 * 2^(-2) + 1 * 2^(-3)

10진수를 n진수로 변환하는 경우

  • 정수 부분과 소수 부분을 구분하여 처리한 후 결과를 합한다
  • 정수 부분의 변환법을 알고리즘으로 표현하면 다음과 같다:
입력값 = 10진수; i = 0;
몫 = 입력값 / r; 나머지 = 입력값 mod r;
결과(i) = 나머지;                       // 나머지를 결과값으로 쓴다
while (몫 != 0)
    입력값 = 몫; i = i + 1;
    몫 = 입력값 / r;
    나머지 = 입력값 mod r;
    결과(i) = 나머지;
end
출력[결과(i), 결과(i-1), …, 결과(0)];   // 결과는 역순으로 출력
  • 이를 C++ 코드로 표현하면 다음과 같다:
#include <iostream>
#include <stack>

// 변환 결과를 출력하는 함수
void PrintResult(std::stack<int> result)
{
	while (!result.empty())
	{
		int top = result.top();
		std::cout << top;
		result.pop();
	}
	std::cout << std::endl;
}

// 10진수의 정수 부분을 r진수로 변환하는 경우 (정수 부분의 경우)
int main()
{
	std::stack<int> result;

	int decimal, r;
	std::cin >> decimal >> r;

	int quotient = decimal / r;
	int remainder = decimal % r;

	result.push(remainder);

	while (quotient != 0)
	{
		decimal = quotient;
		quotient = decimal / r;
		remainder = decimal % r;

		result.push(remainder);
	}

	PrintResult(result);
}
  • 소수 부분의 변환법을 알고리즘으로 표현하면 다음과 같다:
입력값 = 10진수;
i = 0;
while (입력값 != 0)
    임시변수 = 입력값 * r;
    결과(i) = 임시변수의 정수 부분;     // 임시변수의 정수 부분을 결과값으로 쓴다
    i = i + 1;
    입력값 = 임시변수의 소수 부분;
end
출력[0, 결과(0), 결과(1), …, 결과(i)];  // 결과는 정순으로 출력
  • 이를 C++ 코드로 표현하면 다음과 같다:
#include <iostream>
#include <vector>

// 변환 결과를 출력하는 함수
void PrintResult(std::vector<int> result)
{
	std::cout << "0.";
	for (size_t i = 0; i < result.size(); i++)
	{
		std::cout << result[i];
	}
	std::cout << std::endl;
}

// 10진수의 정수 부분을 r진수로 변환하는 경우 (소수 부분의 경우)
int main()
{
	std::vector<int> result;

	double decimal, r;
	std::cin >> decimal >> r;

	while (decimal != 0)
	{
		double temp = decimal * r;
		int integer_portion = static_cast<int>(temp);
		result.push_back(integer_portion);

		double decimal_portion = temp - integer_portion;
		decimal = decimal_portion;
	}

	PrintResult(result);
}

2진수를 8진수 또는 16진수로 변환하는 경우

  • 8진수의 자릿값은 8은 2진수의 가중치(자릿값)인 2를 3제곱한 값이므로 정수부와 소수부를 구분하는 소수점 기호(‘.’)를 기준으로 각각 양의 방향과 음의 방향으로 3자리씩 묶어서 변환해 적어주면 된다
  • 16진수의 자릿값인 16은 2진수의 가중치인 2를 4제곱한 값이므로 위와 마찬가지로 소수점 기호를 기준으로 각각 양의 방향과 음의 방향으로 4자리씩 묶어서 변환해 적어주면 된다
<끝>