获取数字最左边两个位的值的最便宜的方法是什么?

What's the cheapest way to get the value of the two leftmost bits of a number?

本文关键字:最便宜 方法 是什么 两个 数字 左边 获取      更新时间:2023-10-16

我想返回 0,1,2 或 3,基于最左边的 2 位是 00 01 10 或 11。

当我想要最右边的两个位时,我只是用%4.我看到我可以将我的 int 右移到正确的位置(如果是 30 位,则为 32(,然后使用 %4,但这是 2 个操作。有没有"一个操作码"的方法?

如果您使用的是 32 位整数,则右移 30 就足够了。

uint32_t get_value(uint32_t val) {
    return val >> 30;
}

如果您使用的是 64 位整数,则需要按以下方式更改移位的值:

uint64_t get_value(uint64_t val) {
    return val >> 62;
}

采用通用解决方案并没有什么坏处:

template <typename UnsignedInteger>
inline UnsignedInteger 
    top_two_bits(UnsignedInteger value)
{
    return value >> ((sizeof(UnsignedInteger) << 3) - 2);
}

如果您决定进一步使用不同的无符号整数类型,只会让事情变得更容易。在任何情况下,编译器都应该能够以与宏或其他方式一样高效的方式来内联整个表达式。

编辑

此外,(这可能有点矫枉过正,但只是为了完善示例(您可以使用简单的模板元编程技术来创建与任何类型的整数无缝协作的东西,而不会影响效率:

template <typename SignedInteger, bool IsSignedInteger>
struct duduce_sign_dispatch_
{
    static inline SignedInteger
        top_two_bits(SignedInteger value)
    {
        return (value >> ((sizeof(SignedInteger) << 3) - 2)) & SignedInteger(3);
    }
};
template <typename UnsignedInteger>
struct duduce_sign_dispatch_<UnsignedInteger, false>
{
    static inline UnsignedInteger
        top_two_bits(UnsignedInteger value)
    {
        return value >> ((sizeof(UnsignedInteger) << 3) - 2);
    }        
};
template <typename Integer>
inline Integer 
    top_two_bits(Integer value)
{
    return duduce_sign_dispatch_<Integer, (~Integer() < 0)>::top_two_bits(value);
}