我当前的代码库中有以下代码段:
// 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
如何根据所使用的具体整型轻松地生成适当的文字?我正在寻找某事
numeric_constants<id_t>::int_with_msb_set();
答案 0 :(得分:1)
您可以利用std::bitset
来检查是否设置了最高有效位。您可以将数字转换为std::bitset
,然后返回最高有效位,例如
template<typename T>
constexpr bool mb_set(T value)
{
constexpr auto size = sizeof(T) * CHAR_BIT;
return std::bitset<size>(value)[size - 1];
}
使用-O2
或-O3
在clang上对其进行测试,从而优化了shr
指令的功能。
答案 1 :(得分:1)
这是一个返回所需蒙版的函数:
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
}
编译器显然可以在编译时找出这些常量值,因此不会造成速度损失。
另一个明显的解决方案将是对每种类型进行专门化处理的结构(类似于std::numeric_limits
)。