按位右移运算符>>未按预期工作



我正在编写一个代码,以查找数字的二进制表示中的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);

将给出n0位(因为i在每次迭代中用0初始化(,并且对于每次迭代都是相同的。相反,您应该获得tNum0位,因为您在下面的代码中对tNum使用移位运算符。此外,您根本不需要i,只需将其删除即可。语句应该是:

int bit = getBit(tNum, 0);// get 0th bit

更重要的一点是,负数的右移>>的结果是实现定义的。可以,ntNum应该使用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(,编译器可能会为您包装它,或者您可以通过内部函数访问它(有很多版本可用(。

最新更新