题外话:
位运算符是在数字底层(即表示数字的32个数位)进行操作的。
ECMAScript 整数有两种类型,即 有符号整数(允许用整数和负数)和 无符号整数(只允许用整数)。有符号整数使用31位表示整数的数值,用第32位表示整数的符号,0表示正数,1表示负数。
正数是以真二进制形式存储的,例如,18的表示法:
也可以将18转成二进制字符串,就能看到它的有效位了:
负数也存储为二进制代码,不过采用的形式是二进制补码。计算二进制补码可以采取以下的步骤:
(1)求这个数字绝对值的的二进制码
(2)求二进制反码(即0变为1,1变为0)
(3)二进制反码加1
例如,要确定-18的二进制表示,先得到18的二进制表示:
0000 0000 0000 0000 0000 0000 0001 0010
计算二进制反码:
1111 1111 1111 1111 1111 1111 1110 1101
反码加1:
1111 1111 1111 1111 1111 1111 1110 1110
因此,-18 的二进制表示为:1111 1111 1111 1111 1111 1111 1110 1110,不过,把负整数转换成二进制字符串后,ECMAScript 并不以二进制补码的形式显示,而是用数字绝对值的二进制代码前面加负号的形式输出:
----------------------------------------------------------------------分割线----------------------------------------------------------------------------
js 中,位运算符包括7种:按位非(NOT)、按位与(AND)、按位或(OR)、按位异或(XOR)、左移、有符号右移、无符号右移。
1、按位非(NOT)
操作符由一个波浪线表示(~),对位求反(0变为1,1变为0),结果是返回数值的反码。
对一个整数 num 按位取反,结果等于 它的相反数减1,即 ~num = -num - 1。
对一个整数两次按位非,可以得到它本身;对一个小数两次按位非,可以得到取整效果。
还可以用一个数和1进行按位&操作来判断其奇偶性,比如 num&1,若为1,则num是奇数;若为0,则num是偶数。
2、按位与(AND)
操作符由一个和号(&)表示,只有在两个数值的对应位都是1时结果才是1,任何一位是0,结果都是0。详细地:
第一个数字中的数位 | 1 | 1 | 0 | 0 |
第二个数字中的数位 | 1 | 0 | 1 | 0 |
结果(&) | 1 | 0 | 0 | 0 |
3、按位或(OR)
操作符由一个竖线符号(|)表示,只有在两个数值的对应位都是0时结果才是0,任何一位是1,结果都是1。详细地:
第一个数字中的数位 | 1 | 1 | 0 | 0 |
第二个数字中的数位 | 1 | 0 | 1 | 0 |
结果(|) | 1 | 1 | 1 | 0 |
4、按位异或(XOR)
操作符由一个插入符号(^)表示,两个数值的对应位只有一个为1时结果才是1,否则为0。详细地:
第一个数字中的数位 | 1 | 1 | 0 | 0 |
第二个数字中的数位 | 1 | 0 | 1 | 0 |
结果(^) | 0 | 1 | 1 | 0 |
“异或运算”有一个特殊运用:连续对两个数a和b进行三次异或运算(aˆ=b; b^=a; a^=b;),可以互换它们的值。
此外:整数与整数本身按位异或得到的是0(因为每两个对应的数字都相同,所以最后返回的都是0)。
整数与0按位异或得到的是其本身,小数与0按位异或可以取整。
5、左移
操作符由两个小于号(<<)表示,会将数值的所有数位向左移动指定的位数,右边的空位用0填充。左移不影响操作数的符号位。
左移0位可以实现取整效果:
6、有符号右移
操作符由两个大于号(>>)表示,会将数值的所有数位向右移动指定的位数,同时保留该数的符号。
移动数位后会造成空位,空位位于数字的左侧,但位于符号位之后。ECMAScript 用符号位的值填充这些空位,创建完整的数字。例如,把 64 右移 5 位,将变为 2:
7、无符号右移
操作符由三个大于号(>>>)表示,会将数值的所有位向右移动指定的位数。无符号右移运算用 0 填充所有空位。对于正数,这与有符号右移运算的操作一样;而负数则被作为正数来处理。