숫자를 문자열로 변환하는 방법
개요 ¶어셈블리(Assembly) 프로그래밍을 하다가 보면 Register 또는 Memory에 저장된 어떤 결과값을 화면에 표시해야 할 필요가 있다. 이때 저장된 결과값을 각 진법에 맞는 자릿수 단위로 문자화하는 변환이 필요하다.
즉, 1234라는 10진수의 결과값이 저장되어 있을때 화면에 10진수로 출력하기 위해서는 1, 2, 3, 4로 자릿수로 분리하고 화면에 출력하기 위한 Ascii값으로 변환하는 과정이 필요하다. 이때 숫자 0은 Ascii 16진수값으로 30H에 해당하고 1은 31H, ... 9는 39H가 된다. 즉, 분리된 1, 2, 3, 4를 화면에 출력하려면 31H, 32H, 33H, 34H 로 출력을 해야 한다는 의미이다. 이론 ¶각 자릿수를 분리하려면 어떻게 하면 될까? 어떠한 값 x가 있을때 이것을 z진법으로 자릿수를 분리하려면
y = x % z 와 같이 나머지를 취하여 가장 낮은 자릿수를 구할수 있다. 그리고 다음자릿수를 구하기 위해서 x = x / z (실수나눗셈이 아니고 정수나눗셈으로 소숫점은 버린다)으로 방금 구했던 가장 낮은 자릿수를 떨궈버릴수 있다. 이와 같은 방법을 반복하여 x가 0이 될때까지 반복하면 각 자릿수가 하나씩 뽑아져 나오게 되는것이다.
조금 응용하여 예를 들어보자. 만약 10진수로 5라는 숫자가 있다. 이것을 2진법으로 자릿수를 분리하려면 어떻게 할까? 먼저 y = 1 = 5 % 2 이다. 이것이 가장 낮은 자릿수가 된다. 그리고 x = 2 = 5 / 2 가 다음 계산할 값이 된다. 이제 다시 y = 0 = 2 % 2 와 같이 밑에서 두번째 자릿수가 된다. 다시 x = 1 = 2 / 2 이 되고 y = 1 = 1 % 2 와 같이 밑에서 세번째 자릿수가 된다. 다시 x = 0 = 1 / 2 가 되어 0이 되므로 끝이 난다. 결국 1, 0, 1로 자릿수가 분리되며 이를 Ascii로 각 자릿수를 변환하면 31H, 30H, 31H가 되게 된다.
이것을 C언어로 표현하면 간단히 다음과 같은 짧은 함수가 작성될수 있다. char * int_to_string(unsigned int s_value /* 변환하고자 하는 값을 입력받는다 */, int s_radix /* 원하는 진법수 입력받는다 */) { /* 배열을 활용하여 0번째 인덱스는 30H가 되는 식으로 자릿수를 Ascii로 변환하는 테이블을 선언한다. */ static const char c_base_ascii[] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 'A', 'B', 'C', 'D', 'E', 'F'}; /* C언어에서 문자열을 반환하기 위해서 static 메모리 공간이 필요하다. 하지만 Thread상황에서 사용할것이라면 malloc으로 할당하여 반환해야 한다. 여기서는 단지 예제를 보이기 위해 간단하게 static을 잡았을뿐이다. 아래에서 buffer를 어떻게 반환하는지 각자 유심히 보기를 바란다 */ static char s_buffer[ 64 ] = {0, }; /* buffer의 끝을 가르키는것으로 offset을 시작한다. */ size_t s_offset = sizeof(s_buffer) - 1; do { s_buffer[--s_offset] = c_base_ascii[ s_value % s_radix /* y = x % z */ ]; s_value /= s_radix; /* x = x / z */ }while(s_value != 0u); /* 값이 0이 될때까지 반복 */ return((char *)(&s_buffer[s_offset])); } 예제 ¶
|
It is Fortune, not wisdom that rules man's life. |