我正在寻找一种可移植的方式来生成前缀位掩码,其中为 n (或 64 或任意整数类型位宽)设置了第一个 0 <= n <= 32 位。
例子:

prefix_bitmask(0)  = 0b00000000000000000000000000000000u
prefix_bitmask(4)  = 0b00000000000000000000000000001111u
prefix_bitmask(32) = 0b11111111111111111111111111111111u
如果我们忽略 n == 0n == 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/

10-15 02:54