将位分配给64位变量

时间:2014-06-12 19:27:11

标签: c bit-manipulation bit bit-shift bitwise-or

我对位操作有点新意。我试图将信息存储在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,它也失败了。为什么呢?

3 个答案:

答案 0 :(得分:4)

表达式的类型通常由表达式本身决定,而不是由它出现的上下文决定。

您的变量u属于int64_t类型(顺便提一下,uint64_t会更好,因为您正在执行按位运算)。

在这一行:

u |= 1 << i;

由于1的类型为int1 << i的类型为int。如果典型地int是32位,则对于较大的i值,这具有未定义的行为。

如果您将此行更改为:

u |= (uint64_t)1 << i;

它应该做你想要的。

您也可以将1更改为1ULL。这使它成为unsigned long long类型,保证至少为64位但必然uint64_t类型相同。

答案 1 :(得分:0)

  1. __ builtin_popcountl将无符号长整数作为其参数,它并不总是64位整数。我个人使用__builtin_popcountll,这需要很长时间。看起来不是你的情况
  2. 默认情况下整数的类型为'int',并且通过将int移动大于或等于32的任何值(确切地说,int的大小为位),您将得到未定义的行为。正确用法:u | = 1LL&lt;&lt;一世;这里的LL代表很长时间。
  3. 零的Oring什么也没做。您不能将位设置为特定值,您应该使用掩码进行OR(如果要将某些位设置为1)或使用掩码的否定进行AND(如果要将某些位设置为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;
相关问题