如何检查整数中是否正好设置了一位



我想写一个函数HasOneBit

  • 接受任何整数类型(有符号或无符号,8到64位(
  • 为CCD_ 2
  • 不会调用未定义的行为

我试图概括这一点:

bool HasOneBit (std::uint64_t value)
{
return value != 0 && (value & (value - 1)) == 0;
}

如果value的类型是一个有符号整数,并且我们将最小值传递给函数,则此下溢。我是否必须将函数重载8次才能实现所有可能性?

以下模板函数满足所有条件(实时演示(:

template <class T>
constexpr bool HasOneBit (T value)
{
static_assert (std::is_integral<T>::value && !std::is_same<T, bool>::value,
"This function should be used only with integers.");
const std::make_unsigned_t<T> unsignedValue = value;
return unsignedValue != 0 && (unsignedValue & (unsignedValue - 1)) == 0;
}

这不会调用未定义的行为,因为value首先被转换为T的无符号对应项。这种转换不会改变value的比特表示。

我认为,该标准的相关报价是这样的(见N4713,[conv.integral]#2(:

如果目标类型是无符号的,则得到的值是与源整数全等的最小无符号整数(模2n,其中n是用于表示无符号类型的位数(。[注意:在2的补码表示中,这种转换是概念性的,比特模式没有变化(如果没有截断(

此规则的更新版本甚至更简单。不确定这是否也适用于无符号到有符号的转换。

否则,结果是与源整数模2N一致的目标类型的唯一值,其中N是目标类型的宽度。

最新更新