c++ - 如何在广义 inttype 上设置/检查 msb?

标签 c++ templates bit-manipulation

我当前的代码库中有以下代码片段:

// uint32_t id; defined somewhere
bool msb_set = id & 0x80000000

并希望将其更改为更灵活的内容:

using id_t = uint64_t;
id_t id;
bool msb_set = id & 0x80000000  // uh-oh, semantic change for any other differently sized inttype

如何根据我使用的具体 inttype 最轻松地生成适当的文字?我正在寻找

numeric_constants<id_t>::int_with_msb_set();

最佳答案

这是一个返回您想要的掩码的函数:

template<typename T>
constexpr T getMsbMask()
{
    if constexpr (std::is_unsigned_v<T>)
        return T(-1) - T(-1) / 2;
    else
        return std::numeric_limits<T>::min();
    // Unsigned branch computes 0b11111... - 0b01111...
    // Signed branch assumes two's complement, which will soon be the standard:
    // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0907r0.html
}

Demo and tests on godbolt .

编译器显然可以在编译时计算出这些常量值,因此不会有任何速度损失。

另一个明显的解决方案就是为每种类型专门化的结构(类似于 std::numeric_limits)。

关于c++ - 如何在广义 inttype 上设置/检查 msb?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54539426/

相关文章:

php - C++ PHP 桌面和 CEF 崩溃 LoadUrl()

c++ - 在 C++17 中使用 noexcept 的 std::function

C++11:为什么私有(private)成员模板可以在类外访问?

c - 在 C 中移动数字

c - 对 32 位整数进行按位操作

C++ Mysql++,老是连接不上!

c++ - 在#include 语句中使用垃圾字符没有编译器错误

javascript - Meteor - 模板中的 {{#each}} 首先加载旧数据,然后重新加载

c++ - 类用作模板参数时继承方法丢失

arrays - 在 XOR 序列上最大化 AND