我正在寻找一种可移植的方式来生成具有第一个 n
的 前缀位掩码为 0 <= n <= 32
设置的位(或 64 或任意整数类型位宽)。
例子:
prefix_bitmask(0) = 0b00000000000000000000000000000000u
prefix_bitmask(4) = 0b00000000000000000000000000001111u
prefix_bitmask(32) = 0b11111111111111111111111111111111u
如果我们忽略 n == 0
的情况,这已经有两种方法可以工作了。或 n == 32
:
// "constructive": set only the required bits
uint32_t prefix_mask1(int i) { return (uint32_t(1) << i) - 1; }
// "destructive": shift unneeded bits out
uint32_t prefix_mask2(int i) { return ~uint32_t(0) >> (32 - i); }
prefix_mask1
32 和 prefix_mask2
失败0 失败,这都是因为大于整数类型的移位是未定义的行为(因为 CPU 只允许使用移位大小的最低 5 位)。
有没有“规范”的方法来解决这个问题而无需分支?
最佳答案
((uint32_t) 1 << i/2 << i-i/2) - 1
.
以上适用于uint32_t
可以替换为任何无符号类型。并且不需要其他更改。其他需要知道位数的选项b
在类型和掩码中 m
= 2<支持> b
-1包括:
((uint32_t) 1 << (i & m)) - 1 - (i >> b)
(来自supercat)
和:
((uint32_t) i >> b) ^ 1) << (i & m)) - 1
(源自 Matt Timmermans 的建议)。
关于c++ - 生成前缀位掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62511125/