题目:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
微机原理基础:
①原码表示法规定:用符号位和数值表示带符号数,正数的符号位用“0”表示,负数的符号位用“1”表示,数值部分用二进制形式表示。
②反码表示法规定:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。
③补码表示法规定:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.
④正零和负零的补码相同,[+0]补=[-0]补=0000 0000
例如: -5
(一共32位)
原码:1000 0000 0000 0000 0000 0000 0000 0101
反码:1111 1111 1111 1111 1111 1111 1111 1010 (符号位不变,将原码逐位取反)
补码:1111 1111 1111 1111 1111 1111 1111 1011 (符号位不变,+1)
对于正数三码一致;我们这里介绍下如何手动计算一个正数的二进制表示。
比如:7的二进制 0111,计算过程如下,不断处以2,直到商为0。
另:
本题输入的是int类型,int类型取值范围:int型为有符号32位整数,占4个字节,取值范围在-2,147,483,648~2,147,483,647之间。
更多参考:https://blog.csdn.net/q304929130/article/details/48104451
思路:对于整数,我们直接转成二进制,然后统计1的个数;
对于0,直接返回0
对于负数,我们首先得到其绝对值,然后逐位取反(得到反码);最后末位+1(得到补码);我们直接统计0的个数,然后用32去减掉
【注意:上述有个取绝对值操作,当 输入为: -2,147,483,648的时候,取绝对值是会溢出的,所以这种情况单独处理,具体见代码】
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 5 // 输入:n:一个int类型的正整数 6 // 输出:binary:n的二进制表示形式 7 // 功能:获取一个正整数的二进制 8 void getBinary(int n, vector<int>& binary) 9 { 10 // 初始化 11 int remainder = n % 2;//余数 12 int quotient = n / 2;//商 13 binary.push_back(remainder); 14 while (quotient != 0) //商 = 0则停止计算 15 { 16 remainder = quotient % 2;//余数 17 quotient = quotient / 2;//商 18 binary.push_back(remainder); 19 } 20 } 21 22 int NumberOf1(int n) 23 { 24 vector<int> binary; 25 int count = 0; // 1的个数 26 // <1> 正数 27 if ( n > 0) 28 { 29 getBinary(n, binary); 30 for (vector<int>::iterator itr = binary.begin(); itr != binary.end(); itr ++) 31 { 32 if (*itr == 1) 33 { 34 count++; 35 } 36 } 37 return count; 38 } 39 // <2> 0 40 else if (n == 0) 41 { 42 return count; 43 } 44 // <3> 特殊情况 45 // https://blog.csdn.net/q304929130/article/details/48104451 46 else if (n == (-2147483648))// int型为有符号32位整数,占4个字节,取值范围在-2,147,483,648~2,147,483,647之间。 47 { 48 return 1; 49 } 50 // <4> 负数 51 else 52 { 53 int nabs = abs(n);// nabs最大取 01111111111111111111111111111111 (2147483647) 54 //n change to Bianry 55 vector<int> binary; 56 getBinary(nabs, binary); 57 //【计算原码】逐位取反 58 for (vector<int>::iterator itr = binary.begin(); itr != binary.end(); itr++) 59 { 60 if (*itr == 1) 61 *itr = 0; 62 else 63 *itr = 1; 64 } 65 // 【计算补码】最后位加1 66 for (int i = 0; i < binary.size(); i++) 67 { 68 //这里有点小技巧 69 if (binary[i] == 0) 70 { 71 binary[i] = 1; 72 break; 73 } 74 else 75 { 76 binary[i] = 0; 77 } 78 } 79 // 统计0的个数 80 for (vector<int>::iterator itr = binary.begin(); itr != binary.end(); itr++) 81 { 82 if (*itr == 0) 83 { 84 count++; 85 } 86 } 87 return (32 - count); 88 } 89 } 90 91 92 int main() 93 { 94 cout << "0 = " << NumberOf1(0) << endl; 95 cout << "3 = " << NumberOf1(3) << endl; 96 cout << "11 = " << NumberOf1(11) << endl; 97 cout << "5 = " << NumberOf1(5) << endl; 98 cout << "7 = " << NumberOf1(7) << endl; 99 cout << "12 = " << NumberOf1(12) << endl; 100 cout << "255 = " << NumberOf1(255) << endl; 101 cout << "-5 = " << NumberOf1(-5) << endl; 102 cout << "-1 = " << NumberOf1(-1) << endl;// 2 应该是32 103 cout << "-127 = " << NumberOf1(-127) << endl; // -2147483648 104 cout << "-2147483648 = " << NumberOf1(-2147483648) << endl; // 1 105 return 1; 106 }
例如:我们通过计算器来验证, 猜测:由于我们是64位系统,这里显示出来是64位;在本题,我们默认是32位系统。
我们看到有一个0;所以 32 - 1 = 31(符合上述代码计算结果。)
同理:32 - 6 = 26;
同理:32 - 31 = 1;