按位右移运算符 >> 未按预期工作
Bitwise right shift operator >> didn't worked as intended
我正在编写代码以查找数字的二进制表示中的个数
代码如下:
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 没有改变它的值
我不明白我哪里做错了
您在循环开始时初始化了 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),您的编译器可能会为您包装,或者您可以通过内部函数访问它(有许多可用版本)。
您要么不需要i
,要么不需要转移tNum
,决定哪个。
例如:
int count = 0;
while(tNum > 0)
{
count += getBit(n,0);
tNum >>= 1;
}
Bitwise right shift operator >> didn't worked as intended
按位右移运算符 >>
按预期工作,但您没有将 >>
运算符的结果存储在任何地方。这个表达式
tNum >> 1;
会将 tNum
的值右移 1
,但此表达式的结果未被使用。
使用 >>=
运算符代替 >>
。应该是:
tNum >>= 1;
这与 tNum = tNum >> 1
相同。
您的代码中的另一个问题:
这个
getBit(n,i);
将给出 n
的 0
th 位(因为 i
在每次迭代中用 0
初始化) 并且每次迭代都是相同的。相反,您应该获得 tNum
的 0
th 位,因为您在下面的代码中对 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;
}
注意:您的代码的实现有改进的余地。我将由您来确定这些改进并对您的代码进行相应的更改。
我正在编写代码以查找数字的二进制表示中的个数
代码如下:
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 没有改变它的值 我不明白我哪里做错了
您在循环开始时初始化了 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),您的编译器可能会为您包装,或者您可以通过内部函数访问它(有许多可用版本)。
您要么不需要i
,要么不需要转移tNum
,决定哪个。
例如:
int count = 0;
while(tNum > 0)
{
count += getBit(n,0);
tNum >>= 1;
}
Bitwise right shift operator >> didn't worked as intended
按位右移运算符 >>
按预期工作,但您没有将 >>
运算符的结果存储在任何地方。这个表达式
tNum >> 1;
会将 tNum
的值右移 1
,但此表达式的结果未被使用。
使用 >>=
运算符代替 >>
。应该是:
tNum >>= 1;
这与 tNum = tNum >> 1
相同。
您的代码中的另一个问题:
这个
getBit(n,i);
将给出 n
的 0
th 位(因为 i
在每次迭代中用 0
初始化) 并且每次迭代都是相同的。相反,您应该获得 tNum
的 0
th 位,因为您在下面的代码中对 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;
}
注意:您的代码的实现有改进的余地。我将由您来确定这些改进并对您的代码进行相应的更改。