我在 Cracking the Coding 面试书中看到了这个问题。
让我们尝试通过“重新措辞”这个问题来解决这个问题 我们将重新措辞这个问题,直到我们得到一些删除所有 if 语句的东西
改写1:如果a > b,返回a;否则,返回 b
改写 2:如果 (a - b) 为负数,则返回 b;否则,返回一个
重新措辞 3:如果 (a - b) 为负,则令 k = 1;否则,令 k = 0 返回 a - k * (a - b)
改写 4:令 c = a - b 令 k = c 的最高有效位 返回 a - k * c
int getMax(int a, int b) {
int c = a - b;
int k = (c >> ((sizeof(int) * CHAR_BIT) - 1)) & 0x1;
int max = a - k * c;
return max;
}
来源:http ://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/098478280X
编辑:即使 ab 溢出,此代码也有效。令 k 等于 ab 的符号,如果 ab >=0,则 k 为 1,否则 k=0。令 q 为 k 的倒数。当 a 为正数或 b 为负数时,上面的代码会溢出,反之亦然。如果 a 和 b 有不同的符号,那么我们希望 k 等于 sign(a)。
/* Flips 1 to 0 and vice-versa */
public static int flip(int bit){
return 1^bit;
}
/* returns 1 if a is positive, and 0 if a is negative */
public static int sign(int a){
return flip((a >> ((sizeof(int) * CHAR_BIT) - 1)) & 0x1);
}
public static int getMax(int a, int b){
int c = a - b;
int sa = sign(a-b); // if a>=0, then 1 else 0
int sb = sign(a-b); // if b>=1, then 1 else 0
int sc = sign(c); // depends on whether or not a-b overflows
/* If a and b have different signs, then k = sign(a) */
int use_sign_of_a = sa ^ sb;
/* If a and b have the same sign, then k = sign(a - b) */
int use_sign_of_c = flip(sa ^ sb);
int k = use_sign_of_a * sa + use_sign_of_c * sc;
int q = flip(k); //opposite of k
return a * k + b * q;
}