You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无分支实现两个uint16_t相加并避免溢出?

无分支实现方案

可以利用无符号整数溢出的定义特性(C标准规定无符号整数溢出是模2^N的合法运算),结合位运算实现无分支逻辑,避免条件跳转。以下是实现代码:

#include <stdint.h>

uint16_t add_with_no_overflow(uint16_t num, uint16_t delta) {
    uint16_t sum = num + delta;
    // 无符号加法溢出时,sum会小于num(因为delta是正整数,正常相加sum >= num)
    uint16_t overflow_mask = -(sum < num); // 溢出时mask为0xFFFF,否则为0
    // 溢出时返回UINT16_MAX,否则返回sum
    return (sum & ~overflow_mask) | (UINT16_MAX & overflow_mask);
}

逻辑解释

  1. 溢出判断:无符号整数加法中,若num + delta溢出,结果会是(num + delta) % 65536,必然小于num(因为delta是正的,正常相加结果不会小于原数)。因此sum < num可以直接作为溢出的判断条件。
  2. 掩码生成:在无符号运算中,-(sum < num)会将布尔值转换为全1或全0的掩码:当条件为真(溢出)时,sum < num的值为1,取负后无符号下是0xFFFF;条件为假时,值为0,取负后还是0。
  3. 结果选择:通过位运算,溢出时用UINT16_MAX覆盖sum,否则直接返回sum,全程没有分支跳转。

另一种等价实现

也可以基于原分支逻辑的条件直接生成掩码,避免先计算sum:

#include <stdint.h>

uint16_t add_with_no_overflow(uint16_t num, uint16_t delta) {
    uint16_t overflow_mask = -(num > UINT16_MAX - delta);
    uint16_t sum = num + delta;
    return (sum & ~overflow_mask) | (UINT16_MAX & overflow_mask);
}

为什么max(num+delta, num)不适用

你之前尝试的方案在溢出时num+delta会小于num,max会返回原num,但需求是溢出时返回UINT16_MAX,因此无法满足要求。而上面的无分支方案通过掩码精准替换了溢出时的结果。

内容的提问来源于stack exchange,提问作者Jonathan Levin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 15:58:10