计算机中的数在内存中都是以二进制新式进行存储的,用位运算就是直接对整数在内存中的二进制位进行操作,因此其执行效率非常高,在程序中尽量使用位运算进行操作,这会大大提高程序的性能。
位操作符
-
&(与运算) 俩个位数都是1时,结果才为1,否则为0
1 & 1 // => 1 1 & 0 // => 0 0 & 1 // => 0 0 & 0 // => 0 1 0 0 1 1 & 1 1 0 0 1 // => 10001
-
|(或运算) 俩个位数都是0时,结果才为0,否则为1
1 | 1 // => 1 1 | 0 // => 1 0 | 1 // => 1 0 | 0 // => 0 1 0 0 1 1 | 1 1 0 0 1 // => 11011
-
^(异或运算) 俩个位相同则为0,不同则为1
1 ^ 1 // => 0 1 ^ 0 // => 1 0 ^ 1 // => 1 0 ^ 0 // => 0 1 0 0 1 1 ^ 1 1 0 0 1 // => 01010
-
<< 左移运算,向左进行移位操作,高位丢弃,低位补 0~~~~
let n = 1 n << 3 // => 8 // 移位前:0000 0000 0000 0000 0000 0000 0000 0001 // 移位后:0000 0000 0000 0000 0000 0000 0000 1000
-
右移运算,向右进行移位操作,对于无符号,高位补0、对于有符号位,高位补符号位
let n = 8 n >> 2 // => 2 // 移位前:0000 0000 0000 0000 0000 0000 0000 1000 // 移位后:0000 0000 0000 0000 0000 0000 0000 0010 let n = -8 n >> 2 // -2 // 移位前:1111 1111 1111 1111 1111 1111 1111 1000 // 移位后:1111 1111 1111 1111 1111 1111 1111 1110
常见位运算问题
-
位操作实现乘法除法
- 数 n 向右移一位,相当于将 n 除以 2;
- 数 n 向左移一位,相当于将 n 乘以 2;
let n = 4; n >> 1 // => 2 n << 1 // => 8
-
位操作交换俩数
// 普通 function swap (a,b){ a = a + b; // 1 + 2 b = a - b; // 3 - 2 a = a - b; // 3 - 1 } // 位操作 function swap (a,b){ a ^= b; // a = (a^b) b ^= a; // b = (b^b)^a = a a ^= b; // a = (a^b)^a = (a^a)^b = b }
-
位操作判断奇偶数
- 只要根据数的最后一位是 0 还是 1 来决定即可,为 0 就是偶数,为 1 就是奇数
if(0 == (n&1)) // 偶数
-
位操作交换符号
- 交换符号将正数变成负数,负数变成正数
let n = -8 ~n + 1 // => 8 let n = 8 ~n + 1 // => -8
-
位操作求绝对值
- 整数的绝对值是其本身,负数的绝对值正好可以对其进行取反加 1 求得,即我们首先判断其符号位(整数右移31位得0,负数右移31位得到-1,即0xffffffff),然后根据符号进行相应得操作
function abs(a){ let i = a>>31; return i == 0? a: (~a+1) }
- 上面的操作可以进行优化,可以将 i == 0的条件判断语句去掉。我们都知道符号位 i 只有俩种情况,即 i=0为正,i=-1为负。对于任何数与0异或都会保持不变,与-1即0xffffffff进行异或就相当于对此数进行取反,因此可以将上面三目运算符转换为((a^i)-i),即整数时 a 与 0 异或得到本身,在减去0,负数时与 0xffffffff异或将a进行取反,然后在加上1,即减去i(i=-1)
function abs(a){ let i = a>>31; return ((a^i)-i) }
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。