我正在编写一个代码来查找数字的二进制表示形式中的个数。
这是代码:
int main(void)
{
int n,tNum,count = 0;
cin >> n;
tNum = n;
while(tNum > 0)
{
int i = 0;
int bit = getBit(n,i);// get bit
if (bit == 1)
{
count++;
}
tNum >> 1;
i++;
}
cout << count << endl;
}
上面的代码给出了一个无限循环,并且
tNum
没有改变它的值。
我不明白我做错了什么。
按位右移运算符 >> 未按预期工作
按位右移运算符
>>
正在按预期工作,但您没有将 >>
运算符的结果存储在任何地方。这个表情
tNum >> 1;
会将
tNum
的值右移 1
,但该表达式的结果未使用。
使用
>>=
运算符代替 >>
。应该是:
tNum >>= 1;
这与
tNum = tNum >> 1
相同。
代码中的另一个问题:
这个
getBit(n,i);
将给出
0
的第 n
th位(因为
i
在每次迭代中都用 0
初始化),并且对于每次迭代都是相同的。相反,您应该获得 0
的第 tNum
th位,因为您在代码中的
tNum
上使用移位运算符。另外,您根本不需要 i
,只需将其删除即可。声明应该是:
int bit = getBit(tNum, 0);// get 0th bit
更重要的一点,负数右移
>>
的结果是实现定义的。可能,您应该使用 unsigned int
类型来表示 n
和 tNum
。
你可以这样做:
int main (void)
{
unsigned int n, tNum;
int count = 0;
cin >> n;
tNum = n;
while(tNum > 0)
{
int bit = getBit(tNum, 0);// get bit
// You can also do
// int bit = tNum & 1;
if (bit == 1)
{
count++;
}
tNum >>= 1;
}
cout << count << endl;
return 0;
}
注意:代码的实现还有改进的余地。我将由您来确定这些改进并在您的代码中进行相应的更改。
您要么不需要
i
,要么不需要换班 tNum
,决定哪一个。
例如:
int count = 0;
while(tNum > 0)
{
count += getBit(n,0);
tNum >>= 1;
}
您在循环开始时初始化
int i = 0;
,因此 i++
不会做任何有用的事情。另外,你不更新tNum
。考虑使用 for()
循环,这意味着将初始化移到循环之外:
for(int i = 0; tNum > 0; i++) {
...
tNum >>= 1;
}
由于您仅在调用
n
时使用 getBit()
,因此您可以重构它以消除 tNum
。移位时更喜欢使用无符号值。 (对我来说)不清楚负值的位计数是否会计算符号位。
#include <iostream>
using namespace std;
int main(void) {
unsigned n;
cin >> n;
unsigned count = 0;
while(n) {
if(n & 0x1) count++;
n >>= 1;
}
cout << count << endl;
}
最后,现代处理器通常有一个指令(popcnt),您的编译器可能会为您包装它,或者您可以通过内部函数访问它(有许多版本可用)。