我对位操作有点新意。我试图将信息存储在int64_t变量中,如下所示:
int64_t u = 0;
for(i=0;i<44;i++)
u |= 1 << i;
for(;i<64;i++)
u |= 0 << i;
int t = __builtin_popcountl(u);
我想要的是将44个1存储在变量u中并确保其余位置都为0,因此“t”返回44.但是,它总是返回64.使用其他变量,例如int32,它也失败了。为什么呢?
答案 0 :(得分:4)
表达式的类型通常由表达式本身决定,而不是由它出现的上下文决定。
您的变量u
属于int64_t
类型(顺便提一下,uint64_t
会更好,因为您正在执行按位运算)。
在这一行:
u |= 1 << i;
由于1
的类型为int
,1 << i
的类型为int
。如果典型地int
是32位,则对于较大的i
值,这具有未定义的行为。
如果您将此行更改为:
u |= (uint64_t)1 << i;
它应该做你想要的。
您也可以将1
更改为1ULL
。这使它成为unsigned long long
类型,保证至少为64位但必然与uint64_t
类型相同。
答案 1 :(得分:0)
答案 2 :(得分:0)
当你移入32位整数的高位并转换为64位时,符号位将延伸到高32位;然后你将设置所有64位OR,因为你的文字&#39; 1&#39;默认情况下是带符号的32位int 。移位也不会影响高32位,因为该值仅为32位;但是,当转换的值为负时,转换为64位。
这可以通过编写第一个循环来修复:
for(i=0;i<44;i++)
u |= (int64_t)1 << i;
此外,此循环不执行任何操作,因为ORing与0不会改变值:
for(;i<64;i++)
u |= 0 << i;