무슨 일로 C 하셨습니까?

[C] 진수 변환기__1.1 본문

C - 이걸 굳이?/유틸리티

[C] 진수 변환기__1.1

OJJJ 2020. 8. 20. 02:04

이전 게시물에 이어서 작성하는 게시물.

 

블로그에 글을 게시할 때 어떤 문체가 좋을지 고민하는 중에 

나에게 블로그를 추천해준 사람이 음/슴체가 어울릴것 같다하니 이제부터 음슴체로 게시하겠음


진수 변환기 1.0에 큰 문제가 발견됨

바로 10진수 이상의 진수에서는 정상적으로 작동하지 않음

 

16진수 표기법에 따라서

10진수 10부터 15까지 각 수는 알파벳 a부터 f 로 표현하는 것이 국룰임

 

그런데 1.0에서는 알파벳으로의 변환을 고려하지 않음

따라서 수정이 필요함

while (1) {
		if (Temp_Number == 0) break;

		int remainder = Temp_Number % ToBit;
		
		if (remainder > 9) result[--MSB] = remainder + 'a' - 10;
		else result[--MSB] = remainder + '0';

		Temp_Number = Temp_Number / ToBit;
	}

다음과 같이 나머지가 10을 넘을 경우 숫자가 아닌 문자로 변환해주면 됨

( remainder는 나머지를 영어로 번역한 것이라고 구글님 께서 알려주심 )

 

   * remainder 변수에 -10을 해주는 이유는 해당 조건문에 들어가기 위해선 이미 10을 넘어버리기 때문에

     알파벳을 맞추기 위해선 10을 낮추어서 변환해야함

 

알파벳은 총 a ~ z 로 26개임

숫자와 알파벳으로 총 표현할 수 있는 수는 0 ~ 9 , a ~ z 로 총 36개.

최대 36진수까지만 표현할 수 있음. 

( 다른 문자를 사용하여 더 표현할 수 있으나 그 이상을 표현하는 것은 의미가 없다고 생각됨 )

따라서 간단한 조건문을 넣어서 제한을 주는게 좋을 것 같음

 

#include <stdio.h>
#include <stdlib.h>

// 10진수를 n진수로 변환
char* NumberConverter(int Number, int ToBit) {

	if (ToBit > 36 || ToBit < 2) {
		printf("Convert Error\n");
		return "Convert Error";
	}

	int MSB = 1;
	int temp = ToBit;
	
	while (1) {
		if (temp > Number) break;
		else {
			temp *= ToBit;
			MSB++;
		}
	}

	char* result = (char*)malloc(sizeof(char) * (MSB+1));
	result[MSB] = 0;

	int Temp_Number = Number;

	while (1) {
		if (Temp_Number == 0) break;

		int remainder = Temp_Number % ToBit;
		
		if (remainder > 9) result[--MSB] = remainder + 'a' - 10;
		else result[--MSB] = remainder + '0';

		Temp_Number = Temp_Number / ToBit;
	}

	return result;
}

10진수를 n진수로 변환했다면

반대로도 변환시켜야함

 

 

void f(char* Number,int FromBit){}

임의의 n진수 숫자를 받아서 10진수로 변환시킬 함수임

해당 숫자가 몇 진수인지 인자로 받아야함

 

	int NumberLength = StringLength(Number);
	int result = 0;
    
	for (int i = NumberLength-1; i >= 0; i--) {
		
	}

일단은 입력 인자가 문자열이기 때문에 문자열의 길이만큼 반복해야함

 

그런데 문자열의 길이를 알 방법이 없으니 간단한 함수를 만들어 사용하겠음

// 문자열의 길이를 알아내는 함수
int StringLength(char* str){
	for (int i = 0;; i++) {
		if (str[i] == 0) return i;
	}
}

 

n진수를 10진수로 바꾸는건 매우 간단함

그냥 n진수의 각 자릿수를 n의 제곱만큼 곱해서 더하면됨

	int weight = 1;
	for (int i = NumberLength-1; i >= 0; i--) {
		result += (Number[i] - '0') * weight;
		weight *= FromBit;
	}

 반복문을 다음과 같이 바꿔주면 간단히 구현할 수 있음

 

그런데 1.0에서 실수한 것과 마찬가지로 10진수가 넘어가는 진수의 경우 알파벳이 추가되므로

		int tempNumber = Number[i];

		if (Number[i] >= 'a') tempNumber -= 'a';
		else tempNumber -= '0';

다음과 같이 조건을 걸어주면 됨

 

 

// n진수를 10진수로 변환하는 함수
int NumberConverter2(char* Number,int FromBit){

	if (FromBit > 36 || FromBit < 2) {
		printf("Convert Error\n");
		return -1;
	}

	int NumberLength = StringLength(Number);
	int result = 0;

	int weight = 1;
	for (int i = NumberLength-1; i >= 0; i--) {

		int tempNumber = Number[i];

		if (Number[i] >= 'a') tempNumber -= 'a';
		else tempNumber -= '0';

		result += tempNumber * weight;
		weight *= FromBit;
	}
	return result;
}

이 함수가 정상 작동하는지는 직접 테스트해보길 바람.

Comments