首页 > 解决方案 > 如何检查整数中是否恰好设置了一位?

问题描述

我想写一个HasOneBit函数

我试图概括这一点:

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

如果 type ofvalue是有符号整数,则会出现下溢,并且我们将最小值传递给函数。我是否必须重载函数 8 次才能实现所有可能性?

标签: c++type-conversioninteger

解决方案


以下模板函数满足所有条件(现场演示):

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):

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2 n其中n是用于表示无符号类型的位数)。[注意:在二进制补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断)。——尾注]

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

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


推荐阅读