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

时间:2017-05-23 21:12:53

标签: c++ bit-manipulation

我希望返回0,1,2或3,因为最左边的2位是00 01 10或11。

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

2 个答案:

答案 0 :(得分:4)

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

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

如果您正在使用64位整数,则需要更改您转移的值:

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

答案 1 :(得分:1)

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

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);
}