class Max {
public:
    int getMax(int a, int b) {
        // write code here
        return (((long long)a+b)+((((long long)a-b)^(((long long)a-b)>>63))-(((long long)a-b)>>63)))/2;
    }
};

解题思路全解析

这段代码的核心是用数学公式 + 位运算实现“无比较求两个整数的最大值”,全程不使用 if-else、比较运算符(>/<),同时解决了整数溢出问题,是面试中“无比较求最大值”的经典解法。以下分4个层面拆解思路:

一、核心原理:最大值的数学公式(整个代码的根基)

对于任意两个整数 ab,最大值可以通过以下数学公式计算:[\max(a,b) = \frac{a + b + |a - b|}{2}]公式逻辑验证

  • a ≥ b|a - b| = a - b,代入公式得 (a+b +a -b)/2 = a(正确);
  • b > a|a - b| = b - a,代入公式得 (a+b +b -a)/2 = b(正确);
  • a = b|a - b| = 0,代入公式得 (a+b)/2 = a = b(正确)。

代码的所有逻辑,都是为了安全实现这个公式(重点解决“绝对值计算”和“溢出问题”)。

二、代码分步拆解(逐段解释作用)

我们把代码拆成5个核心部分,逐一说明:

return (((long long)a+b) + ((((long long)a-b) ^ (((long long)a-b)>>63)) - (((long long)a-b)>>63))) / 2;

(long long)a + b

a

强制转为64位整数

long long

,再和

b

相加,避免

int

溢出(比如

a=2^31-1, b=1

时,

a+b

超32位int范围)。

(long long)a - b

计算

a-b

的差值

x

,同样转64位避免溢出,记为

x = (long long)a - b

x >> 63

获取

x

的符号位(64位

long long

的符号位在第63位):<br>- 若

x ≥ 0

(正数/0),右移63位结果为

0

;<br>- 若

x < 0

(负数),右移63位结果为

-1

(64位补码全1)。

(x ^ (x>>63)) - (x>>63)

位运算计算 `

整体

/ 2

代入最大值公式,完成 `(a+b+

三、关键细节(新手最容易踩坑的点)

1. 为什么用 long long 而不是 int

int 是32位,取值范围是 -2^31 ~ 2^31-1,如果 ab 都是大数(比如 a=2^31-1, b=1),a+b 会超出 int 范围,触发溢出(数值变成负数),导致计算错误。long long 是64位,取值范围极大(-2^63 ~ 2^63-1),能容纳 int 范围内任意两个数的和/差,彻底避免溢出。

2. 为什么用 >>63 而不是 >>31

因为我们把 a-b 转成了64位 long long,64位整数的符号位在第63位(32位int的符号位在第31位)。如果用 >>31,64位负数右移31位得到的不是 -1,而是 0xFFFFFFFF80000000,会导致绝对值计算错误。

四、测试用例验证(直观理解逻辑)

用例1:正数场景 a=5, b=3
  1. x = (long long)5 - 3 = 2(正数);
  2. x>>63 = 2>>63 = 0
  3. 绝对值计算:(2^0)-0 = 2
  4. 最大值计算:(5+3 +2)/2 = 10/2 = 5(正确)。
用例2:负数场景 a=-5, b=3
  1. x = (long long)-5 -3 = -8(负数);
  2. x>>63 = -8>>63 = -1
  3. 绝对值计算:(-8 ^ -1) - (-1) = 7 +1 =8
  4. 最大值计算:(-5+3 +8)/2 =6/2=3(正确)。
用例3:溢出场景 a=2147483647, b=1
  1. x = 2147483647 -1 = 2147483646(正数);
  2. a+b = 2147483648long long 能存,无溢出);
  3. 最大值计算:(2147483648 + 2147483646)/2 = 2147483647(正确)。

核心思路总结

  1. 底层逻辑:用数学公式 (a+b+|a-b|)/2 绕开比较操作,实现最大值计算;
  2. 位运算技巧:通过 x>>63 获取符号位,再用 (x^sign)-sign 计算绝对值(兼容正负);
  3. 工程细节:用 long long 解决32位int的溢出问题,保证计算安全;
  4. 关键坑点:64位整数必须用 >>63 取符号位,32位用 >>31,否则符号判断错误。

这段代码是“数学公式 + 位运算 + 溢出处理”的结合,既满足“无比较”的要求,又保证了工程上的正确性,是面试中该题的最优解之一。