先说下位掩码,这是看JavaScript位运算的初衷。
位掩码的概念
什么是位掩码,先看个有趣的智力题,据说也是很多公司的面试题目。
小白鼠试毒问题
有1000瓶药水,其中只有一瓶有毒,小白鼠喝了会死。问,最多需要多少只小白鼠可以试出来哪瓶有毒?
答案:
将1000瓶药水用二进制编码,第一瓶表示为01, 第二瓶表示为10, 第三瓶表示为11,…,第1000瓶表示为1111101000。将这1000个二进制数进行
|
(按位或)运算得到一个数值(当然结果也是二进制),我们暂且称这个数值为小B。这个按位或|
运算步骤对应我们的实际操作是,将这些二进制数中当前位是1
的药水进行混合,最终得到10瓶(因为小B的长度就是10嘛)新的混合药水。位。那么我们用10只小白鼠分别去喝这10瓶药水。那么24小时候,10只小白鼠有生有死。生记为0, 死记为1,按之前的顺排列好后又得到一个二进制数, 我们称之为小C。最后,我们用小B跟小C进行&
(按位与)运算,得到的二进制结果,就是有毒药水瓶的二进制编号。
下面是一个简化版的题目,只有3瓶药水,用于验证上述步骤的正确性。
// 三瓶药水分别记为 Y1, Y2, Y3
// 0b开头是二进制数的表示语法
var Y1 = 0b01,
Y2 = 0b10,
Y3 = 0b11;
// 实际上,为了方便表示,Y1, Y2, Y3可以分别用十进制数1,2,3表示
var B = Y1 | Y2 | Y3; // 按位或运算;
/**
Y1: 0 1
Y2: 1 0
Y3: 1 1
----
1 1
所以B = 0b11;
*/
console.log(B.toString(2).length);
// 上面可以看到B的长度是2,那么我们需要两只小白鼠
// 两只小白鼠分别记做 M1, M2
// 根据B的运算过程,我们知道小白鼠M1喝Y2,Y3, 小白鼠M2喝Y1, Y3
// 接下来我们要验证结果,假设第一瓶Y1有毒, 那么小白鼠M1活,M2死,得到结果是 0b01;
var C = 0b01;
console.log( (B&C