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

问题描述 投票:0回答:3

我正在编写一个代码来查找数字的二进制表示形式中的个数。

这是代码:

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
没有改变它的值。 我不明白我做错了什么。

c++ bitwise-operators
3个回答
1
投票

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

按位右移运算符

>>
正在按预期工作,但您没有将
>>
运算符的结果存储在任何地方。这个表情

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;
}

注意:代码的实现还有改进的余地。我将由您来确定这些改进并在您的代码中进行相应的更改。


0
投票

您要么不需要

i
,要么不需要换班
tNum
,决定哪一个。

例如:

    int count = 0;
    while(tNum > 0)
    {
        count += getBit(n,0);
        tNum >>= 1;
    }

0
投票

您在循环开始时初始化

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),您的编译器可能会为您包装它,或者您可以通过内部函数访问它(有许多版本可用)。

© www.soinside.com 2019 - 2024. All rights reserved.