按位操作符-按位与(AND)

1,002 阅读4分钟

上一章我们学习了按位操作符 带你认识按位操作符

这一章我们整理一下按位运算的经典案例

回顾

使用按位操作符的数,会先转成 32 位比特序列,也就是32 位的有符号的整数

如果这个数是正数,如果大于 23112^{31}-1,只会保留低 32 位, 高于 32 位的数不存储;

如果这个数是负数,如果小于 231-2^{31},只会保留低 32 位, 高于 32 位的数不存储;

按位与(&)

两个二进制数, 它们对应位的数都是 1 时, 结果为 1, 否则, 结果为 0。

浮点数转整数

12.12 & 12.12   //12
Math.PI & Math.PI  //3

JavaScript 默认将数字存储为 64 位浮点数,但按位运算都是以 32位的二进制整数执行。

两个相同的数按位运算后, 结果只会保留整数部分,小数部分在转行阶段不存储。

Infinity & Infinity //0
Number.MAX_VALUE & Number.MAX_VALUE //0

如果一个数大于 23112^{31}-1 由于按位运算时只会保留低 32 位运算, 高于 32位的数丢弃, 结果就不准确了。

判断数字奇偶

function assert(x) {
   return x & 1;
}
assert(3)   //1    如果返回1是奇数,否则是偶数。

x 是任意正整数,这里我们用 x = 3举例子,那么, 3 & 1 转成32 位比特序列就是:

     3 (base 10) = 00000000000000000000000000000011 (base 2)
     1 (base 10) = 00000000000000000000000000000001 (base 2)
                   --------------------------------
 3 & 1 (base 10) = 00000000000000000000000000000001 (base 2) = 1 (base 10)

3 & 1 的结果是 1,是奇数。我们再来一个例子:

     4 (base 10) = 00000000000000000000000000000100 (base 2)
     1 (base 10) = 00000000000000000000000000000001 (base 2)
                   --------------------------------
 4 & 1 (base 10) = 00000000000000000000000000000000 (base 2) = 0 (base 10)

4 & 1的结果是 0,是偶数。

统计二进制中 1 的个数

编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为 汉明重量).)。

function hammingWeight(x) {
  count = 0  
  while(x){  
    x = x & (x - 1);  
    count++;  
  } 
  return count;
}
hammingWeight(6) //2

这里我们用x = 6带入, 那么 x - 1 = 5, 5 & 6 的结果是多少, 我们画图理解。

     6 (base 10) = 00000000000000000000000000000110 (base 2)
     5 (base 10) = 00000000000000000000000000000101 (base 2)
                   --------------------------------
 6 & 5 (base 10) = 00000000000000000000000000000100 (base 2) = 4 (base 10)   count++;
      3(base 10) = 00000000000000000000000000000011 (base 2)
                   --------------------------------
  4 & 3(base 10) = 00000000000000000000000000000000 (base 2) = 0 (base 10)   count++;

我们一共执行了两次x = x & (x - 1), 所以也会执行两次count++, 第三次开始执行 while 时, x = 0, 跳出循环,返回结果 2

通过画图理解, 因为二进制是满 2 进 1,所以 x & (x - 1) 恰好可以把x 的二进制位中的最低位的 1 变成 0。 每次都会把二进制 x 中的一个 1 变成 0 , 统计执行x & (x - 1) 异或的次数, 就是 “1” 的个数。

总结

  • 二进制的最末位为0表示该数为偶数,最末位为1表示该数为奇数
  • x & n - 1 , 总能把x最低位的 1变为 0, 其他位保持不变。