首页 > 解决方案 > 使用 C++ 从数字中获取 x 到 y 位

问题描述

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

标签: c++c++11bit-manipulation

解决方案


所以看来我误读了你的问题,这就是为什么我不喜欢使用评论,几分钟后你就无法纠正它们。但是我被警告不要发布此类问题的答案,但这里有一个基本示例:

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

推荐阅读