以下代码输出0、1、32、33。至少可以说这是反直觉的。但是,如果将文字1替换为带注释的常量“ONE”,则循环运行良好。
这是与gcc 4.6.2和-std = c++ 0x一起使用的。
#include<iostream>
#include<cstdint>
using namespace std;
int main()
{
int64_t bitmask = 3;
int64_t k;
const int64_t ONE = 1;
cout<<"bitmask = "<<bitmask<<endl;
for(k=0; k<64; k++)
{
if(bitmask & (1<<k))
{
cout<<"k="<<k<<endl;
}
}
return 0;
}
编辑
问题:正如Ben指出的那样,默认情况下1被视为32位宽。当合作数为64位时为什么不将其提升为64位。
解决方案
否。<
复制自比尔(Bill)的以下评论
最佳答案
这是一个问题:(1<<k)
。1
是适合int
的整数文字。
如果平台上的int
少于64位,则当(1<<k)
很大时,k
将在循环结束时具有未定义的行为。在您的情况下,编译器使用Intel位移位指令,并且未定义的行为以Intel定义的移位大于操作数大小的方式出现-高位被忽略。
您可能需要(1LL<<k)
标准说了什么(第5.8节expr.shift
):
这与“通常的算术转换是针对
算术或枚举类型的操作数。”,例如加减运算符。
在C++ 03和C++ 11之间,该语言没有变化。