Following my previous question,我需要创建一个由固定比特数设置为1的值。我使用了以下函数:
void MaskAddRange(UINT& mask, UINT first, UINT count)
{
mask |= ((1 << count) - 1) << first;
}
但是,正如发现的那样,count = 32
无效。 1 << count
在这种情况下理论上的结果是未定义的行为(或结果),而实际上在x86上是1,因为移位操作数被模数为32。
我想修复此表达式以便在这种极端情况下正常工作。什么是最简单/最好/最有效的方法?
通过分支(if
,?
)处理这个特定情况有点简单,虽然很难看,但我敢打赌它效率也很低。
另一种方法是将移位操作数提升为更大的类型(64位)。我的意思是:
void MaskAddRange(UINT& mask, UINT first, UINT count)
{
mask |= (UINT(unsigned __int64(1) << count) - 1) << first;
}
有更好的方法吗?
答案 0 :(得分:1)
除非你能证明,否则永远不要认为任何事情是无效的。 if-else可能在您的架构+操作系统上比升级到64位更高效。我认为除了你已发布的那两种方法之外,还没有任何其他理智的方法。
我会选择if-else,因为记录处理极端情况的意图。提升到64位并不表示意图。
答案 1 :(得分:0)
您可以使用
mask |= (UINT(-1)<<first) & (UINT(-1)>>(32-first-count))
哪个更复杂但在任何情况下都应该有效。该表达式相对于其他解决方案的效率可能取决于架构和编译器。