std::midpoint比(a + b) / 2更安全,因其通过位运算或分段逻辑避免整数溢出、浮点精度丢失和指针越界,支持整型、浮点、指针且类型需一致,c++20引入,推荐替代手动计算。

std::midpoint 为什么比 (a + b) / 2 更安全
直接用 (a + b) / 2 计算中点,在整数类型上容易溢出——比如 int a = INT_MAX, b = 1,a + b 就触发未定义行为。而 std::midpoint(C++20 引入)专为解决这个问题设计:它不依赖加法,而是通过位运算或分段逻辑避免溢出,对整型、浮点、指针都有效。
它不是“更精确”,而是“不崩”。尤其在数组索引、二分查找、区间划分等场景下,能守住边界不越界。
怎么用 std::midpoint 处理整数中点
必须包含 <numeric></numeric>,且两个参数类型要一致(或可隐式转换)。对有符号整数,结果向零取整;对无符号,就是数学意义的中点(向下取整)。
-
std::midpoint(1, 5)→3 -
std::midpoint(-3, 7)→2(不是2.0,仍是 int) -
std::midpoint(UINT_MAX - 2u, UINT_MAX)→ 安全返回UINT_MAX - 1u,而(a + b) / 2会溢出
注意:std::midpoint 不接受混合类型,比如 std::midpoint(1, 5L) 编译失败;需显式统一类型,如 std::midpoint(static_cast<long>(1), 5L)</long>。
浮点数和指针也能用,但语义不同
对 float/double,std::midpoint 仍比 (a + b) / 2 更稳健:当 a 和 b 符号相反且绝对值极大时(如 1e30 和 -1e30),加法可能产生 inf 或精度丢失,而 std::midpoint 会按比例缩放再还原,保持有限结果。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
对指针,只允许同数组内两个指针,例如:
int arr[10]; auto mid = std::midpoint(arr, arr + 9); // 指向 arr[4],安全
若指针不指向同一数组(或 one-past-the-end),行为未定义——这点和 std::distance 一样,容易被忽略。
兼容性与替代方案
如果你还在用 C++17 或更早,std::midpoint 不可用。常见手写替代:
- 对无符号整数:
a + (b - a) / 2(前提是b >= a) - 对有符号整数:需先判断大小,再用
a + (b - a) / 2或b - (b - a) / 2避免负溢出 - 用
std::div或std::lldiv手动处理商余,但开销略大
升级到 C++20 后,优先用 std::midpoint——它经过标准库实现优化,且语义清晰。别再写 (low + high) >> 1 了,那个在负数上错得离谱。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










