题目描述
将一个长度最多为30位数字的十进制非负整数转换为二进制数输出。
输入
多组数据,每行为一个长度不超过30位的十进制非负整数。
(注意是10进制数字的个数可能有30个,而非30bits的整数)
输出
每行输出对应的二进制数。
样例输入
985
211
1126
样例输出
1111011001
11010011
10001100110
思路:
本题中数字可能达到30位,远超于longlong型,所以只能用字符串对数字进行存储;
模拟十进制转二进制的手算过程,不断除基取余;
代码如下:
#include <cstdio>
#include <cstring>
char n[200], ans[200];
int num[200];
int main()
{
while (scanf ("%s", n) != EOF) {
int len = strlen (n);
for (int i = 0; i < len; i++) { //将字符转化为数字;
num[i] = n[i] - '0';
}
int carry, count = 0, j = 0;
while (j < len) {
ans[count++] = num[len - 1] % 2 + '0'; //通过最后一位值确定输出1还是0;
for (int i = j, carry = 0; i < len; i++) {
int sum = (carry * 10 + num[i]) / 2; //模拟进行除法;
carry = num[i] % 2; //判断除2是否除尽;
num[i] = sum;
}
if (num[j] == 0) j++; //最高位数字为0,下移一位;
}
for (int i = count - 1; i >= 0; i--) { //数组从高位输出;
printf ("%c", ans[i]);
}
printf ("\n");
}
return 0;
}
关键点:
for (int i = j, carry = 0; i < len; i++) {
int sum = (carry * 10 + num[i]) / 2; //模拟进行除法;
carry = num[i] % 2; //判断除2是否除尽;
num[i] = sum;
}
这道题目看了很久的代码才看懂,写一下自己的理解:这段代码模拟除法从高位开始除2,当除不尽时,乘十加上下一位的值。
因为是用字符串存储,一个位置只存储了一位数字,所以用一个循环处理所有数字;
如若不理解可先手写一十进制数进行2进制的转换。
从这题学到while(~scanf ("%s", n)) 与 while(scanf ("%s", n) != EOF)等价;
scanf函数的返回值就为其成功读入的参数的个数,当读取文件到文件末尾导致无法读取时,函数会返回-1,C语言中EOF来代表-1;
~是取反,-1的补码为1111 1111 1111 1111,所以取反后正好为0,所以两种写法等价;