我正在编写一个代码,以查找数字的二进制表示中的1个数
这是代码:
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没有改变它的值我不明白我哪里做错了
位右移运算符>gt;没有按预期工作
按位右移运算符>>
按预期工作,但您没有将>>
运算符的结果存储在任何位置。此表达式
tNum >> 1;
将CCD_ 3的值右移CCD_。
使用>>=
运算符而不是>>
。应该是:
tNum >>= 1;
这与tNum = tNum >> 1
相同。
代码中的另一个问题:
这个
getBit(n,i);
将给出n
的0
第位(因为i
在每次迭代中用0
初始化(,并且对于每次迭代都是相同的。相反,您应该获得tNum
的0
第位,因为您在下面的代码中对tNum
使用移位运算符。此外,您根本不需要i
,只需将其删除即可。语句应该是:
int bit = getBit(tNum, 0);// get 0th bit
更重要的一点是,负数的右移>>
的结果是实现定义的。可以,n
和tNum
应该使用unsigned int
类型。
你可以做:
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;
}
由于在对getBit()
的调用中只使用n
,因此可以对其进行重构以消除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(,编译器可能会为您包装它,或者您可以通过内部函数访问它(有很多版本可用(。