정수를 2진수로 변환
문제
unsigned int 값을 앞에 불필요한 0이 없는 2진수 문자열로 변환하시오.
char* to_binary_string(unsigned int value);
| value | result |
|---|---|
0 |
"0" |
1 |
"1" |
7 |
"111" |
11 |
"1011" |
255 |
"11111111" |
풀이
2로 계속 나눈 뒤 뒤집기
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <assert.h>
char* to_binary_string(unsigned int value)
{
char* result = malloc((sizeof(value) * CHAR_BIT) + 1);
size_t length = 0;
do
{
result[length++] = (value % 2) + '0';
value /= 2;
}
while (value > 0);
for (size_t i = 0; i < length / 2; i++)
{
char temp = result[i];
result[i] = result[length - 1 - i];
result[length - 1 - i] = temp;
}
result[length] = '\0';
return result;
}
int main(void)
{
char* result = to_binary_string(0);
assert(strcmp(result, "0") == 0);
free(result);
result = to_binary_string(1);
assert(strcmp(result, "1") == 0);
free(result);
result = to_binary_string(7);
assert(strcmp(result, "111") == 0);
free(result);
result = to_binary_string(11);
assert(strcmp(result, "1011") == 0);
free(result);
result = to_binary_string(255);
assert(strcmp(result, "11111111") == 0);
free(result);
return 0;
}
사람이 종이에 적어서 변환하는 방법을 코드로 옮긴 것이다.
예를 들어 11을 2진수로 바꿀 때는 2로 계속 나누고 오른쪽에 나머지를 적는다.
2로 나누기 때문에 나머지는 제수보다 작은 0, 1 둘 중 하나가 된다.
2 ) 11 ... 1
2 ) 5 ... 1
2 ) 2 ... 0
2 ) 1 ... 1
0
계산이 끝난 후 나머지를 아래에서 위로 읽으면 2진수 1011이 완성된다.
코드도 같은 방식으로 value를 2로 나누면서 나머지를 result에 저장한다.
이때 나머지는 2진수의 오른쪽 끝자리부터 나오기 때문에 result에는 거꾸로 저장된다.
종이에 적은 나머지를 아래에서 위로 읽듯이, 저장된 문자열을 뒤집는다.
while이 아닌 do ... while 문을 사용한 이유는 value가 0일 때 따로 조건문으로 처리하지 않고,
value가 0이어도 본문이 한 번 실행되게 만들기 위해서다.