代码之家  ›  专栏  ›  技术社区  ›  MistyD Harish Kumar Kailas

用C++从一个数字中获得X到Y位

  •  -1
  • MistyD Harish Kumar Kailas  · 技术社区  · 6 年前

    假设我有一个十进制数字1033 如何获取0到9之间的位(在这种情况下,它将是十进制的9) 在这种情况下,如何从第10位到第15位得到位(1位小数)。C++中有一个选项可以帮助我完成这一点以及如何使用它。提前谢谢

    0 回复  |  直到 6 年前
        1
  •  0
  •   Richard    6 年前

    所以我似乎误解了你的问题,这就是为什么我不喜欢使用评论,几分钟后你就不能纠正它们。但有人警告我不要发布此类问题的答案,但这里有一个基本的例子:

    #include <iostream>
    #include <iomanip>
    #include <stdexcept>
    #include <type_traits>
    
    template<typename UnsignedType>
    
    UnsignedType mask(UnsignedType value, size_t low_bit, size_t high_bit) {
        static_assert(std::is_unsigned_v<UnsignedType>, "UnsignedType must be an unsigned type.");
        if (low_bit <= high_bit && high_bit < std::numeric_limits<UnsignedType>::digits) {
            UnsignedType mh = (1 << (high_bit+1)) - 1;
            UnsignedType ml = (1 << (low_bit)) - 1;
            UnsignedType mask = mh & (~ml);
            std::cout << "Mask     " << std::hex << mask << '\n';
            return value & mask;
        } else {
            throw std::logic_error("Bit range error.");
        }
    }
    
    int main() {
        auto r1 = mask<uint32_t>(1033, 0, 9);
        std::cout << "Result 1 " << r1 << '\n';
        auto r2 = mask<uint32_t>(1033, 10, 15) >> 10; // Also shift right to zero base the result.
        std::cout << "Result 2 " << r2 << '\n';
        return 0;
    }
    

    如果只使用编译时已知的少量位偏移量,则可以利用它:

    #include <iostream>
    #include <iomanip>
    #include <stdexcept>
    #include <type_traits>
    
    template<typename UnsignedType, size_t LowBit, size_t HighBit>
    
    UnsignedType mask2(UnsignedType value) {
        static_assert(std::is_unsigned_v<UnsignedType>, "UnsignedType must be an unsigned type.");
        static_assert((LowBit <= HighBit) && (HighBit < std::numeric_limits<UnsignedType>::digits),
                      "Bit range error");
        constexpr UnsignedType mh = (1 << (HighBit + 1)) - 1;
        constexpr UnsignedType ml = (1 << (LowBit)) - 1;
        constexpr UnsignedType mask = mh & (~ml);
        std::cout << "Mask     " << std::hex << mask << '\n';
        return value & mask;
    }
    
    int main() {
        auto r1 = mask2<uint32_t,0,9>(1033);
        std::cout << "Result 1 " << r1 << '\n';
        auto r2 = mask2<uint32_t,10,15>(1033) >> 10; // Also shift right to zero base the result.
        std::cout << "Result 2 " << r2 << '\n';
        return 0;
    }