c++ - 如何检查整数中是否恰好设置了一位?
问题描述
我想写一个HasOneBit
函数
- 接受任何整数类型(有符号或无符号,8 到 64 位),
- 是
constexpr
, - 不会调用未定义的行为。
我试图概括这一点:
bool HasOneBit (std::uint64_t value)
{
return value != 0 && (value & (value - 1)) == 0;
}
如果 type ofvalue
是有符号整数,则会出现下溢,并且我们将最小值传递给函数。我是否必须重载函数 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):
如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2 n其中n是用于表示无符号类型的位数)。[注意:在二进制补码表示中,这种转换是概念性的,位模式没有变化(如果没有截断)。——尾注]
此规则的更新版本更加简单。不确定,这是否也适用于无符号到有符号的转换。
否则,结果是与源整数模2 N一致的目标类型的唯一值,其中N是目标类型的宽度。
推荐阅读
- amazon-web-services - CloudWatch 中的 Lambda 报告中缺少 Init Duration 字段
- reactjs - 如何将保存文件数据的状态设置为空并上传?
- python - Kivy-Buildozer Android 打包不起作用('buildozer' 未被识别为内部或外部命令、可运行程序或批处理文件。)
- javascript - 使用 Provider 时 React.createContext 抛出错误
- python - 如何与机器人命令一起运行 loop.create_task()?
- css - 背景图像仅在 Edge 中显示截断
- batch-file - For 循环使用用户输入来组合文件 - 使用命令
- intellij-idea - GDSL 用于在注解中定义闭包的委托
- python - 创建新列但在熊猫中获得收入
- c - 部分不受信任的应用程序中的地址检查