std::midpoint 通过 a + (b – a) / 2 避免加法溢出,仅对同号有符号整型且 b ≥ a 时完全定义;不保障浮点精度,也不校验索引有效性或区间非空。
std::midpoint 是 C++20 引入的、唯一被标准保证「不溢出」的中点计算工具,适用于整型和指针类型;对浮点数它不提供额外安全优势,反而可能引入精度偏差。
为什么 std::midpoint 能防整数溢出?
传统写法 (a + b) / 2 在 a 和 b 同号且绝对值较大时极易溢出(如 INT_MAX + 1)。std::midpoint 内部采用位运算或分段逻辑:对有符号整数,它等价于 a + (b - a) / 2(无溢出前提下),避免了加法峰值。
- 仅当
a和b同为有符号整型,且b >= a时,std::midpoint(a, b)的行为完全定义且无溢出风险 - 若
b ,结果仍正确(例如 <code>midpoint(10, 2)返回6),但底层实现需处理符号,部分编译器可能生成稍多指令 - 对无符号类型(如
unsigned int),它同样安全,因为减法不会溢出(自动回绕),但语义上仍要求你理解“中点”在模算术下的含义
std::midpoint 对浮点数没用,还可能更糟
对 float 或 double,std::midpoint 只是调用 (a + b) / 2 —— 标准未要求它规避浮点溢出或精度损失。更严重的是:当 a 和 b 量级相差极大时(如 a = 1e30, b = 1.0),a + b 可能直接舍入为 a,导致结果错误;而手工用 a + (b - a) / 2 反而更稳健。