彭学长学补码

下课后,刘老师给了彭学长一道关于补码的编程题,想检验他补码的学习情况,当然这对于爱学习的彭学长来说简简单单,很快就完成程序的编写,并把题目发给了你,想看看你有没有和他不一样的解法。
题目:

有一共N个数字1和0(为了方便输出,题目保证N为4的倍数,且4 ⩽ n ⩽ 12),
其中1的数量为x(0 ⩽ x ⩽ N)
从小到大输出由这些1和0组成的所有二进制补码和其对应的十进制数
格式为:
十进制数 = 二进制补码(补码每四位之间用一个空格分开,一行一个)
注:第一位永远为符号位

输入格式:

输入在一行内给出N和x,对应题目的N和x,二则之间用空格隔开
即:N x

输出格式:

例如:8位二进制补码0
0 = 0000 0000
(注意=左边和右边各有一个空格 左边为十进制 右边为二进制,且每一组输出都有一次换行)

输入样例1:

4 2

输出样例1:

-7 = 1001
-6 = 1010
-4 = 1100
3 = 0011
5 = 0101
6 = 0110

输入样例2:

12 3

输出样例2:

-2045 = 1000 0000 0011
-2043 = 1000 0000 0101
-2042 = 1000 0000 0110
-2039 = 1000 0000 1001
-2038 = 1000 0000 1010
-2036 = 1000 0000 1100
-2031 = 1000 0001 0001
-2030 = 1000 0001 0010
-2028 = 1000 0001 0100
-2024 = 1000 0001 1000
-2015 = 1000 0010 0001
-2014 = 1000 0010 0010
-2012 = 1000 0010 0100
-2008 = 1000 0010 1000
-2000 = 1000 0011 0000
-1983 = 1000 0100 0001
-1982 = 1000 0100 0010
-1980 = 1000 0100 0100
-1976 = 1000 0100 1000
-1968 = 1000 0101 0000
-1952 = 1000 0110 0000
-1919 = 1000 1000 0001
-1918 = 1000 1000 0010
-1916 = 1000 1000 0100
-1912 = 1000 1000 1000
-1904 = 1000 1001 0000
-1888 = 1000 1010 0000
-1856 = 1000 1100 0000
-1791 = 1001 0000 0001
-1790 = 1001 0000 0010
-1788 = 1001 0000 0100
-1784 = 1001 0000 1000
-1776 = 1001 0001 0000
-1760 = 1001 0010 0000
-1728 = 1001 0100 0000
-1664 = 1001 1000 0000
-1535 = 1010 0000 0001
-1534 = 1010 0000 0010
-1532 = 1010 0000 0100
-1528 = 1010 0000 1000
-1520 = 1010 0001 0000
-1504 = 1010 0010 0000
-1472 = 1010 0100 0000
-1408 = 1010 1000 0000
-1280 = 1011 0000 0000
-1023 = 1100 0000 0001
-1022 = 1100 0000 0010
-1020 = 1100 0000 0100
-1016 = 1100 0000 1000
-1008 = 1100 0001 0000
-992 = 1100 0010 0000
-960 = 1100 0100 0000
-896 = 1100 1000 0000
-768 = 1101 0000 0000
-512 = 1110 0000 0000
7 = 0000 0000 0111
11 = 0000 0000 1011
13 = 0000 0000 1101
14 = 0000 0000 1110
19 = 0000 0001 0011
21 = 0000 0001 0101
22 = 0000 0001 0110
25 = 0000 0001 1001
26 = 0000 0001 1010
28 = 0000 0001 1100
35 = 0000 0010 0011
37 = 0000 0010 0101
38 = 0000 0010 0110
41 = 0000 0010 1001
42 = 0000 0010 1010
44 = 0000 0010 1100
49 = 0000 0011 0001
50 = 0000 0011 0010
52 = 0000 0011 0100
56 = 0000 0011 1000
67 = 0000 0100 0011
69 = 0000 0100 0101
70 = 0000 0100 0110
73 = 0000 0100 1001
74 = 0000 0100 1010
76 = 0000 0100 1100
81 = 0000 0101 0001
82 = 0000 0101 0010
84 = 0000 0101 0100
88 = 0000 0101 1000
97 = 0000 0110 0001
98 = 0000 0110 0010
100 = 0000 0110 0100
104 = 0000 0110 1000
112 = 0000 0111 0000
131 = 0000 1000 0011
133 = 0000 1000 0101
134 = 0000 1000 0110
137 = 0000 1000 1001
138 = 0000 1000 1010
140 = 0000 1000 1100
145 = 0000 1001 0001
146 = 0000 1001 0010
148 = 0000 1001 0100
152 = 0000 1001 1000
161 = 0000 1010 0001
162 = 0000 1010 0010
164 = 0000 1010 0100
168 = 0000 1010 1000
176 = 0000 1011 0000
193 = 0000 1100 0001
194 = 0000 1100 0010
196 = 0000 1100 0100
200 = 0000 1100 1000
208 = 0000 1101 0000
224 = 0000 1110 0000
259 = 0001 0000 0011
261 = 0001 0000 0101
262 = 0001 0000 0110
265 = 0001 0000 1001
266 = 0001 0000 1010
268 = 0001 0000 1100
273 = 0001 0001 0001
274 = 0001 0001 0010
276 = 0001 0001 0100
280 = 0001 0001 1000
289 = 0001 0010 0001
290 = 0001 0010 0010
292 = 0001 0010 0100
296 = 0001 0010 1000
304 = 0001 0011 0000
321 = 0001 0100 0001
322 = 0001 0100 0010
324 = 0001 0100 0100
328 = 0001 0100 1000
336 = 0001 0101 0000
352 = 0001 0110 0000
385 = 0001 1000 0001
386 = 0001 1000 0010
388 = 0001 1000 0100
392 = 0001 1000 1000
400 = 0001 1001 0000
416 = 0001 1010 0000
448 = 0001 1100 0000
515 = 0010 0000 0011
517 = 0010 0000 0101
518 = 0010 0000 0110
521 = 0010 0000 1001
522 = 0010 0000 1010
524 = 0010 0000 1100
529 = 0010 0001 0001
530 = 0010 0001 0010
532 = 0010 0001 0100
536 = 0010 0001 1000
545 = 0010 0010 0001
546 = 0010 0010 0010
548 = 0010 0010 0100
552 = 0010 0010 1000
560 = 0010 0011 0000
577 = 0010 0100 0001
578 = 0010 0100 0010
580 = 0010 0100 0100
584 = 0010 0100 1000
592 = 0010 0101 0000
608 = 0010 0110 0000
641 = 0010 1000 0001
642 = 0010 1000 0010
644 = 0010 1000 0100
648 = 0010 1000 1000
656 = 0010 1001 0000
672 = 0010 1010 0000
704 = 0010 1100 0000
769 = 0011 0000 0001
770 = 0011 0000 0010
772 = 0011 0000 0100
776 = 0011 0000 1000
784 = 0011 0001 0000
800 = 0011 0010 0000
832 = 0011 0100 0000
896 = 0011 1000 0000
1027 = 0100 0000 0011
1029 = 0100 0000 0101
1030 = 0100 0000 0110
1033 = 0100 0000 1001
1034 = 0100 0000 1010
1036 = 0100 0000 1100
1041 = 0100 0001 0001
1042 = 0100 0001 0010
1044 = 0100 0001 0100
1048 = 0100 0001 1000
1057 = 0100 0010 0001
1058 = 0100 0010 0010
1060 = 0100 0010 0100
1064 = 0100 0010 1000
1072 = 0100 0011 0000
1089 = 0100 0100 0001
1090 = 0100 0100 0010
1092 = 0100 0100 0100
1096 = 0100 0100 1000
1104 = 0100 0101 0000
1120 = 0100 0110 0000
1153 = 0100 1000 0001
1154 = 0100 1000 0010
1156 = 0100 1000 0100
1160 = 0100 1000 1000
1168 = 0100 1001 0000
1184 = 0100 1010 0000
1216 = 0100 1100 0000
1281 = 0101 0000 0001
1282 = 0101 0000 0010
1284 = 0101 0000 0100
1288 = 0101 0000 1000
1296 = 0101 0001 0000
1312 = 0101 0010 0000
1344 = 0101 0100 0000
1408 = 0101 1000 0000
1537 = 0110 0000 0001
1538 = 0110 0000 0010
1540 = 0110 0000 0100
1544 = 0110 0000 1000
1552 = 0110 0001 0000
1568 = 0110 0010 0000
1600 = 0110 0100 0000
1664 = 0110 1000 0000
1792 = 0111 0000 0000

参考代码:

#include 

struct node{
    int num;
    char bit[15];
} p[1000];

int main(void)
{
    int n, x;
    scanf("%d %d", &n, &x);
    int siz = 0;
	/**
	 * 思路:n个数字,每个数字可以为 0和1,那么就有 2^n 种可能性,直接遍历即可
	 * 然后对于每一种可能,判断 1 的个数是否为 x 个
	 * 如果是的,就直接加入数组
	 */
    for (int i = 0; i < (1 << n); ++i) {
		// 计算 i 中 1 的个数
		// 这里可以直接使用函数 __builtin_popcount() 计算 1 的个数
        int tmp = i, cnt = 0;
        while (tmp > 0) {
            ++cnt;
            tmp -= tmp & (-tmp);
        }
		// 如果 i 中的 1 的个数刚好是 x 个,就加入 p 数组
        if (cnt == x) {
			// 这里将 i 转换为二进制字符串存入数组
            tmp = i;
            p[siz].bit[n] = '\0';
            for (int j = n - 1; j >= 0; --j) {
                if (tmp & 1) p[siz].bit[j] = '1';
                else p[siz].bit[j] = '0';
                tmp >>= 1;
            }
			// 在变化的时候要考虑是否为负数,即第一位是否为 ‘1’
			// 如果是的,利用补码的性质进行转换
			if (p[siz].bit[0] != '1') p[siz].num = i;
			else p[siz].num = i - (1 << n);
            ++siz;
        }
    }
	// 对 p 数组 插入排序 (从小到大)
    for (int i = 1; i < siz; ++i) {
        int now = i - 1;
        struct node tmp = p[i];
        while (now >= 0 && p[now].num > tmp.num) {
            p[now + 1] = p[now];
            --now;
        }
        p[now + 1] = tmp;
    }
	// 依次输出 每个数 及其 二进制数,注意格式要求,每四个二进制数就有一个空格!
    for (int i = 0; i < siz; ++i) {
        if (i) printf("\n");
        printf("%d = ", p[i].num);
        for (int j = 0; j < n; j += 4) {
            if (j) printf(" ");
            printf("%c%c%c%c",  p[i].bit[j], p[i].bit[j + 1], p[i].bit[j + 2], p[i].bit[j + 3]);
        }
    }
    
    return 0;
}

你可能感兴趣的:(计组原理,计算机组成原理)