我目前正在开展一个项目,我需要一些项目。我使用uint64_t
的数组作为bitset。
我目前的问题是,无论何时我想设置或检查一下,我都需要进行这样的操作:
uint64_t index = 42;
bArr[index/64] |= (((uint64_t)1)<<(index%64));
我可以用一些聪明的和以及 bitshift 操作重写除法和模数,但是我关注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);
}
}
我能以聪明的方式绕过这个演员吗?我认为性能可能会受到每次读/写...
的演员的影响答案 0 :(得分:4)
<<
运算符的结果类型是左操作数的类型(在整数提升之后),这是您需要使用正确类型的原因:1
的类型为{{1但是你需要输入int
。
您可以使用:
uint64_t
或
(uint64_t) 1
或
UINT64_C(1) /* you have to include <stdint.h> */
(对于最后一个假设1ULL
在你的系统中是64位很可能)。
但它们都是等价的:所有这些表达式都是整型常量表达式,它们的值是在编译时计算的,而不是在运行时计算的。
答案 1 :(得分:3)
演员本身并不影响演出。它是一个编译时构造,它告诉编译器表达式的类型。
在这种情况下,它们都是整数转换和表达式,因此不会对性能产生影响。
答案 2 :(得分:3)
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
是可选的。
答案 3 :(得分:1)
如果我理解正确,你需要一个至少64位长的文字1。您可以1ull
编写1
而不是unsigned long long
,而无需任何演员。这会创建一个值{1}的Mail::send([], [], function($message) use($to, $title, $email_body)
{
$message->setBody($email_body)->to($to)->subject($title);
});
字面值。但是,不保证类型不会长于64位,所以如果你依赖它只是64位,那么你可能需要一个强制转换。< / p>