面试题 16.07. 最大数值
编写一个方法,找出两个数字a和b中最大的那一个。不得使用if-else或其他比较运算符。
思路:因为要求不能使用if_else 或者比较运算符,在这里构造一个公式
class Solution {
public:
int maximum(int a, int b) {
return a * k + b * (k ^ 1);
}
};
公式中的k应为0,或者1,且应满足:
(1)当 a < b 时,k = 0,此时满足 k ^ 1 = 1,return b;
(2)当 a > b 时,k = 1,此时满足 k ^ 1 = 0,return a;
那么如何让 k 满足我们的要求的呢?这里可以用算术运算+位运算操作:判断 a - b 的最高位(符号位),即:
当 a - b < 0 时,a - b 的最高位为 1,此时,k 应该为 0;
当 a - b > 0 时,a - b 的最高位为 0,此时,k 应该为 1;
所以,k的值应与a-b的最高符号位相反。
class Solution {
public:
int maximum(int a, int b) {
// 计算 int 类型的位数,避免不同系统下长度不同
int bitlen = sizeof(a) * 8;
// 计算 a 的符号位,b 的符号位
// C/C++ 中负数右移最高位会补 1,因此需要转成无符号类型后再右移
int asign = static_cast<unsigned>(a) >> (bitlen - 1);
int bsign = static_cast<unsigned>(b) >> (bitlen - 1);
// 假设 a 与 b 异号,计算 k 的值
int k = asign ^ 1;
// 当 a 和 b 异号时,asign ^ bsign ^ 1 为 0,由于 逻辑与运算 的短路性,将不再计算后半行代码,避免溢出
// 当 a 和 b 同号时,asign ^ bsign ^ 1 为 1,此时会执行后半行代码,重新对 k 赋值
int temp_cond = (asign ^ bsign ^ 1) && (k = static_cast<unsigned>(a - b) >> (bitlen - 1) ^ 1);
return a * k + b * (k ^ 1);
}
};
参考:https://leetcode-cn.com/problems/maximum-lcci/solution/zhen-liang-zhe-dao-ti-jing-ke-yi-zhe-yan-vj0s/