被遗忘的位运算符

前言

整数:ECMAScript整数包括有符号整数(允许正数和负数)和无符号整数(只允许正数),在ECMAScript中,所有整数字面量默认都是有符号整数

  • 有符号整数:数值范围从-2147483648到2147483647

  • 无符号整数:数值范围从0到4294967295

    1
    2
    3
    var i = 18,  j = -18;
    alert(i.toString(2)); // -> '10010'
    alert(j.toString(2)); // -> '-10010'

位运算符NOT(~)

1、把运算符转为32位二进制数字

2、再转为它的二进制反码

3、把二进制反码转为浮点数

简:对数字求负,然后减1,比如~25 === -26

位运算符AND(&)

它对数字的二进制进行操作,把数字转换为二进制后,把每个数字的数对齐,不够补0,然后以下面的规则进行OR运算:

1 对 1 -> 1

1 对 0 -> 0

0 对 1 -> 0

0 对 0 -> 0

因此, 16 & 15 = 0, 15 & 14 = 14

1
2
3
4
5
16:  10000
15: 01111
----------------
00: 00000
00: 0
1
2
3
4
5
15:  01111
14: 01110
----------------
00: 01110
00: 14

位运算符OR(|)

它对数字的二进制进行操作,把数字转换为二进制后,把每个数字的数对齐,不够补0,然后以下面的规则进行AND运算:

1 对 1 -> 1

1 对 0 -> 1

0 对 1 -> 1

0 对 0 -> 0

因此, 16 | 15 =16, 15 | 14 = 15

1
2
3
4
5
16:  10000
15: 01111
----------------
00: 11111
00: 16
1
2
3
4
5
15:  01111
14: 01110
----------------
00: 01111
00: 15

左移运算(<<)

有符号右移运算(>>)

无符号右移运算(>>>)

用例

“4”的整数次幂(链接:http://web.jobbole.com/86290/)

给定一个32位有符号整数(32 bit signed integer),写一个函数,检查这个整数是否是“4”的N次幂,这里的N是非负整数。不使用常规循环和遍历

思路:利用二进制位数 和 位运算符 & 解决

1
2
3
4
40 = 1B
41 = 100B
42 = 10000B
43 = 1000000B

也就是每个数比上一个数的二进制后面多两个零嘛。最重要的是,“4”的幂的二进制数只有 1 个“1”。判断一个二进制数只有 1 个“1”,只需要:

1
(num & num - 1) === 0

但是,二进制数只有 1 个“1”只是“4”的幂的必要非充分条件,因为“2”的奇数次幂也只有 1 个“1”。所以,我们还需要附加的判断:

1
(num & num - 1) === 0 && (num & 0xAAAAAAAA) === 0

为什么是 num & 0xAAAAAAAA === 0? 因为这个确保 num 的二进制的那个 “1” 出现在“奇数位”上,也就确保了这个数确实是“4”的幂,而不仅仅只是“2”的幂

最终结果:

1
2
3
4
5
function isPowerOfFour(num) {
return num > 0
&& (num & (num-1)) === 0
&& (num & 0xAAAAAAAA) === 0;
};