C - BitArray - 设置uint64_t的单个位

Mat*_*ias 6 c casting bit-shift bitarray memory-efficient

我正在开发一个项目,我需要一些项目.我正在uint64_t为bitset 使用一个数组.

我目前的问题是,无论何时我想设置或检查一下,我都需要做这样的操作:

uint64_t index = 42;
bArr[index/64] |= (((uint64_t)1)<<(index%64)); 
Run Code Online (Sandbox Code Playgroud)

我可以重写师,并与一些聪明的模位位移操作为好,但我担心的演员1.我需要这个演员,因为否则它1被视为32位单元.如本示例所示 - 如果没有强制转换,则输出错误:

uint64_t bArr[4];                           // 256 bits 
bArr[0] = bArr[1] = bArr[2] = bArr[3] = 0;  // Set to 0

uint64_t i = 255;
bArr[i/64] = (bArr[i/64] | (((uint64_t)1)<<(i%64))); 

uint32_t i2;
for (i2 = 0; i2 < 256; i2++) {
  if ((bArr[i2/64] & (((uint64_t)1)<<(i2%64))) != 0) {
    printf("bArray[%" PRIu32 "] = 1\n", i2);
  }
}
Run Code Online (Sandbox Code Playgroud)

我能以聪明的方式绕过这个演员吗?我当时认为表演可能会受到每次读/写的影响......

oua*_*uah 4

运算符的结果类型<<是左操作数的类型(在整数提升之后),这就是为什么您需要使用正确的类型:1is of typeint但您需要 type uint64_t

您可以使用:

(uint64_t) 1
Run Code Online (Sandbox Code Playgroud)

或者

UINT64_C(1)  /* you have to include <stdint.h> */
Run Code Online (Sandbox Code Playgroud)

或者

1ULL  
Run Code Online (Sandbox Code Playgroud)

(对于最后一个,假设unsigned long long您的系统是 64 位,这很可能)。

但它们都是等价的:所有这些表达式都是整型常量表达式,它们的值是在编译时计算的,而不是在运行时计算的。