我正在运行以下程序:(网址:http://ideone.com/aoJoI5)
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long long int N=pow(2, 36);
cout << N <<endl;
int count = 0;
cout << "Positions where bits are set : " << endl;
for(int j=0; j<sizeof(long long int)*8; ++j){
if(N&(1<<j)){
++count;
cout << j << endl;
}
}
return 0;
}
这个程序输出为:
68719476736
Positions where bits are set :
31
63
现在我正在使用N = 2 ^ 36,这意味着第36位应该是1而没有别的,但为什么程序给我位置31和63?我的程序出了什么问题?
我有一个观察结果,如果我们使用N = 2 ^ {exp},其中exp&gt; = 32,它总是给出设置位的位置为31和63.任何人都可以解释为什么会发生这种情况?
答案 0 :(得分:6)
如果int
为32位长,则1<<j
会进行过多调整并调用未定义的行为。
以下是我对原因的猜测:
j
变为31时,1
位到达符号位。N
计算按位AND,该值将进行符号扩展,因此从第31位到第63位(0原点)的位变为1。N
中的第36位(0-origin)为1,因此按位AND的结果将为非零。j
为63时,如果使用IA-32 CPU,则要移位的宽度将被屏蔽为5位,因此它将被解释为31并且会发生相同的事情。要避免此未定义的行为,请使用unsigned long long
值来转移1ull<<j
。
请注意,使用long long
并不好,因为将1
位移到sign位会调用未定义的行为。