C - BitArray -设置uint64_t的单位



我目前正在做一个项目,在这个项目中我需要位集。我使用一个uint64_t 's数组作为bitset。

我目前的问题是,每当我想设置或检查位时,我需要做这样的操作:

uint64_t index = 42;
bArr[index/64] |= (((uint64_t)1)<<(index%64)); 

我可以用一些聪明的位移操作重写除法和取模,但是我担心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 "] = 1n", i2);
  }
}

我可以用一个聪明的方法绕过这个石膏吗?我在想,演出可能是受每次读/写的演员的影响…

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

(uint64_t) 1

UINT64_C(1)  /* you have to include <stdint.h> */

1ULL  

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

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

强制转换本身并不影响性能。它是一个编译时构造,告诉编译器表达式的类型。

在这种情况下,它们都是整数类型转换和表达式,所以应该没有性能影响。

C提供了宏,可以将整型常量扩展为int_leastN_t类型。

INTN_C(value)
UINTN_C(value)

例子
#include <stdint.h>.
bArr[index/64] |= UINT64_C(1) << (index%64);

一般中最好避免强制转换。有时强制转换会意外地使表达式比希望的窄。


UINT64_C的好处:uint_least_64_t/int_least_64_t类型必须存在(C99)。int64_t/uint64_t是可选的

如果我理解正确的话,您需要至少64位长的文字1。您可以通过编写1ull而不仅仅是1来实现这一点,而不需要任何强制类型转换。这将创建一个值为1的unsigned long long字面值。但是,不能保证该类型不超过64位,因此,如果您依赖于它恰好是64位,则可能需要进行强制类型转换。

相关内容

  • 没有找到相关文章

最新更新