位运算 互斥性返回更大的数

202 阅读2分钟
  • 题目

不能通过任何比较操作,返回 a 和 b 中更大的数

  • 通过互斥性进行加法操作,让返回 a 或返回 b 只能满足其中一个条件
function getMax(a, b) {
  // 异或操作,这里的作用相当于取反
  function revert(n) {
    return n ^ 1;
  }

  // 获取符号位
  // 因为 revert 异或后,所以负数为 0,正数为 1
  function sign(n) {
    return revert((n >> 31) & 1);
  }

  const c = a - b;
  const singc = sign(c); // 获取 c 的正负,大数可能溢出,正数为 1,负数为 0
  const _signc = revert(singc); // 和 singc 的取值相反

  return a * singc + b * _signc; // 利用互斥性返回更大的数
}

因为直接a-b的结果可能存在大数溢出的情况,所以优化版本采用如下的互斥逻辑 返回a更大的情况:

  • a、b 符号相同则不可能溢出,则 a - b 的值需要 > 0;
  • a、b 符号不同,那么必须 a > 0;
function getMax2(a, b) {
  // 异或操作,这里的作用相当于取反
  function revert(n) {
    return n ^ 1;
  }

  // 获取符号位
  // 因为 revert 异或后,所以负数为 0,正数为 1
  function sign(n) {
    return revert((n >> 31) & 1);
  }

  const c = a - b;
  const singc = sign(c); // 获取 c 的正负
  const singa = sign(a); // 获取 a 的正负
  const singb = sign(b); // 获取 b 的正负
  const _sameab = singa ^ singb; // a、b正负是否相同,相同为0,不同为1
  const sameab = revert(singab); // 取反,a、b正负相同为1,不同为0
  const returna = _sameab * singa + sameab * singc; // 返回a更大的两种情况,1:a、b符号相同则不可能溢出,则a-b的值的符号要和a相同;2:a、b符号不同,那么必须 a>0
  // 这里的互斥性:
  // 当 _sameab 为 1 表明 a、b 符号不同,那么 sameab 就为 0 互斥,只考虑 _sameab * singa 的结果
  // 当 _sameab 为 0 表明 a、b 符号相同,那么 sameab 就为 1 互斥,只考虑 sameab * singc 的结果
  const returnb = revert(returna); // 返回 b 的情况

  return a * returna + b * returnb; // 利用互斥性返回更大的数
}