문제
컴퓨터는 내부적으로 0과 1 두 개의 숫자만을 사용하여 모든 프로그램이 동작된다.
이렇게 두 개의 숫자만으로 이루어진 수를 이진수라 한다.
2진수를 입력받아 10진수로 변환하여 출력하는 프로그램을 작성하시오.
입력
0과 1로만 이루어져 있는 30자리 이하의 2진수를 입력받는다.
출력
입력된 2진수를 10진수로 변환하여 출력한다.
예제1
10101
21
10진수란?
어떤 수를 나타낼 때, 각 자리에 0부터 9까지 10개의 숫자로 나타내는 표시방법을 10진법이라 하고 이렇게 표시된 수를 10진수라 한다.
"위치적 기수법"으로 표시되므로 자리수에 따라 가중치가 달라진다.
한 자리의 값이 10이상이면 자리올림이 발생되므로 10진수 12345는 다음과 같이 식으로 표시할 수 있다.
또한 다음과 같이 Horner's rule(method)라는 방법으로 표시할 수 있다.
12345 = (((((0 * 10 + 1) * 10) + 2) * 10 + 3) * 10 + 4) * 10 + 5
1 에는 10 이 4번 곱해지므로 10000 이 되고,
2 에는 10 이 3번 곱해지므로 2000 이 되고,
3 에는 10 이 2번 곱해지므로 300 이 되고,
4 에는 10 이 1번 곱해지므로 40 이 되고,
5 는 그대로 사용하므로 5가 되며 이들을 더한결과이므로 12345 이다.
2진수란?
어떤 수를 나타낼 때, 각 자리에 0 또는 1 두 가지의 숫자로 나타내는 표시방법을 2진법이라 하고 이렇게 표시된 수를 2진수라 한다.
"위치적 기수법"으로 표시되므로 자리수에 따라 가중치가 달라진다.
한자리의 값이 2 이상이면 자리올림이 발생되므로 2진수 10111은 다음과 같이 식으로 표시할 수 있다.
또한 다음과 같이 Horner's rule(method)이라는 방법으로 표시할 수 있다.
10111 = (((((0 * 2 + 1) * 2) + 0) * 2 + 1) * 2 + 1) * 2 + 1
2진수를 10진수로 변환하기 위해서는 위와 같은 식을 이용해서 계산을 하면 된다.
위의 식을 정리하면 2진수 10111은
위의
이러한 성질을 재귀적으로 이용하면 앞에서부터 계속 2를 곱하면서 더해 나가는 방법으로 쉽게 프로그래밍을 할 수 있다.
이를 Horner's rule(method)라고 한다.
10101을 변환하는 과정을 살펴보자.
• 앞에서 한자리 1을 10진수로 변환하면 0 * 2 + 1 = 1 이다.
• 앞에서 두자리 (10)까지 변환하면 (0 * 2 + 1) * 2 + 0 = 2 이다.
• 앞에서 세자리 (101)까지 변환하면 (((0 * 2 + 1) * 2) + 0) * 2 + 1 = 5 이다.
• 앞에서 네자리 (1011)까지 변환하면 ((((0 * 2 + 1) * 2) + 0) * 2 + 1) * 2 + 1 = 11 이다.
• 앞에서 다섯자리 (10111)까지 변환하면 (((((0 * 2 + 1) * 2) + 0) * 2 + 1) * 2 + 1) * 2 + 1 = 23 이다.
10진수를 2진수로 변환하기
10진수를 2진수로 변환하기 위해서는 위의 과정을 역순으로 하여 2씩 묶어가면서 나머지를 1의 자리부터 확정해 나가면 된다.
10진수 21을 2진수로 변환하는과정은 다음과 같다.
2) 23 ... 1 23 % 2 = 1 이고 이는 2의 0 제곱 자리의 수가 된다.
2) 11 ... 1 11 % 2 = 1 이고 이는 2의 1 제곱 자리의 수가 된다.
2) 5 ... 1 5 % 2 = 1 이고 이는 2의 2 제곱 자리의 수가 된다.
2) 2 ... 0 2 % 2 = 0 이고 이는 2의 3 제곱 자리의 수가 된다.
1 ... 1 1 % 2 = 1 이고 이는 2의 4 제곱 자리의 수가 된다.
더이상 나눌 수 없으므로 나누는 작업을 멈추고 역순으로 2로 나눈 나머지를 출력한다.
※ 피젯수가 0이 될때까지 실행하지 않고 피젯수(나누어지는 수)가 젯수(나누는 수) 보다 작으면 출력하는 이유는
10진수 0 을 2진수로 변환할 때 0 으로 변환할 수 있도록 하기 위함이다.
#include <stdio.h>
#include <string.h>
int change(char t[])
{
int i, len, ten=0;
len = strlen(t);
for (i=0; i<len; i++)
{
ten = ten*2+(t[i]-'0'); //앞자리까지의 값에 2를 곱하고 현재의 값을 더한다.
}
return ten;
}
int main()
{
char two[35];
scanf("%s", two);
printf("%d\n", change(two));
return 0;
}
코드분석
change 함수는 문자열로 된 이진수를 받아서 10진수로 변환하여 리턴하는 함수이다.
t[i]는 문자 ‘0’ 또는 ‘1’이므로 숫자로 변환하기 위해서는 ‘0’을 빼주어야 한다.
참고로 change 함수는 재귀적 성질을 이용하여 아래와 같이 재귀함수로 작성할 수도 있다.
#include <stdio.h>
#include <string.h>
int change(char t[], int len)
{
if (len==0) return 0;
return change(t, len-1) * 2 + (t[len-1]-'0');
}
int main()
{
char two[35];
scanf("%s", two);
printf("%d\n", change(two, strlen(two)));
return 0;
}