题目描述
将一个长度最多为30位数字的十进制非负整数转换为二进制数输出。
输入
多组数据,每行为一个长度不超过30位的十进制非负整数。
(注意是10进制数字的个数可能有30个,而非30bits的整数)
输出
每行输出对应的二进制数。
样例输入
985
211
1126
样例输出
1111011001
11010011
10001100110
思路:
考虑普通的十进制数转换为二进制所使用的除基取余法
11除以2,商5,余1
5除以2,商2,余1
2除以2,商1,余0
1除以2,商0,余1 商0时算法终止
余数从后往前输出,得11转换为2进制的结果是1011
此题难点在于数很大,不能像直接像11一样整体除2得结果
考虑113,除以2,商56,余1
我们可以这样做,从高位开始
1 % 2 = 1 //将余数传给下一位(相当于乘10,1*10+1=11)
1 / 2 = 0 //百位变成0
11 % 2 = 1 //再把余数给下一位(相当于乘10,1*10+3=13)
11 / 2 = 5 //十位变成5
13 % 2 = 1 //最终余1
13 / 2 = 6 //个位变成6
这样就完成了111除以2商得056,余1的过程(相当于除基取余法的第一步)
这一步进行完之后,111变成了056,并且结果数组会记录余数1
由于此时的最高位变成了0,所以移动到下一位
接下来再仿照这些步骤,依次进行,注意仅当最高位变成0时才移到下一位
直到最后除2的最终商为0时停止,注意字符与数字之间ASCII码的转换
#include <cstdio>
#include <cstring>
void trans(int a, char num[], int b);//从a进制转换到b进制
int main() {
char num[31];
while (scanf("%s", num) != EOF) {
trans(10, num, 2);
}
return 0;
}
void trans(int a, char num[], int b) {
char ans[101];//10^30约等于2的100次方
int len = strlen(num);
int i, j, m, n, k = 0;
for (i = 0; i < len;) {
m = 0;
for (j = i; j < len; j++) {
n = (m * a + num[j] - '0') % b;//当前这轮的余数
num[j] = (m * a + num[j] - '0') / b + '0';//变更当前位的数
m = n;//把余数传给下一位
}
ans[k++] = char(m + '0');//记录该轮的余数
while (num[i] == '0') {//仅当最高位变成0时才移到下一位
i++;
}
}
for (i = k - 1; i >= 0; i--) {//从后往前输出余数
printf("%c", ans[i]);
}
printf("\n");
}