如何高效判断两个int32_t类型数值的差值为0或1?
两数差值为0/±1的优化实现方案
先回顾你提到的两种常规实现方式:
常规实现方式
方案1:基于无符号差值判断
uint32_t diff = abs(num1 - num2); bool isZeroOrOne = (diff == 0 || diff == 1);
方案2:直接枚举所有差值情况
int32_t diff = num1 - num2; bool isZeroOrOne = (diff == 0 || diff == 1 || diff == -1);
更优化的实现方案
位运算或无分支的算术判断在多数硬件平台上执行效率更高,尤其适合循环密集型场景,以下分类型给出优化实现:
针对无符号整数(uint32_t)
利用无符号数的异或特性:当两数相等时异或结果为0,差值为1时异或结果为1,差值大于1时异或结果必然大于1,因此可以直接判断:
bool isZeroOrOne = (num1 ^ num2) <= 1;
也可以用减法结合逻辑判断,避免异或:
bool isZeroOrOne = ((num1 - num2) <= 1) && ((num2 - num1) <= 1);
无符号减法不会出现溢出问题,因为无符号数的减法是模2^N运算,当num1 < num2时,num1 - num2会得到一个很大的正数,自然大于1,所以第二个判断(num2 - num1) <=1只会在num2 ≤ num1+1时成立,正好对应差值绝对值≤1的情况。
针对有符号整数(int32_t)
方法1:利用平方判断
通过计算差值的平方,仅当差值为-1、0、1时平方结果≤1,避免多条件分支:
int32_t diff = num1 - num2; bool isZeroOrOne = (diff * diff) <= 1;
注:我们的场景是差值绝对值≤1,不会出现平方溢出问题。
方法2:无分支绝对值判断
利用有符号数的补码特性计算绝对值,再判断是否≤1:
int32_t diff = num1 - num2; // 位运算计算绝对值:正数不变,负数取反加1 uint32_t abs_diff = (diff ^ (diff >> 31)) - (diff >> 31); bool isZeroOrOne = abs_diff <= 1;
这种方式避免了调用abs函数的开销,直接通过位运算完成绝对值计算。
方法3:安全范围判断
通过判断两数的相互范围,避免减法溢出(当num1或num2为极值时,减法可能触发未定义行为),转换为无符号数处理更安全:
bool isZeroOrOne = ((uint32_t)num1 <= (uint32_t)num2 + 1) && ((uint32_t)num2 <= (uint32_t)num1 + 1);
无符号数的加法溢出是定义良好的模运算,不会出现未定义行为。
内容的提问来源于stack exchange,提问作者mad0x60
相关产品推荐
相关产品推荐

