计算机中的数在内存中都是以二进制新式进行存储的,用位运算就是直接对整数在内存中的二进制位进行操作,因此其执行效率非常高,在程序中尽量使用位运算进行操作,这会大大提高程序的性能。

位操作符

  • &(与运算) 俩个位数都是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

常见位运算问题

  1. 位操作实现乘法除法

    • 数 n 向右移一位,相当于将 n 除以 2;
    • 数 n 向左移一位,相当于将 n 乘以 2;
    let n = 4;
    n >> 1 // => 2
    n << 1 // => 8
  2. 位操作交换俩数

    // 普通
    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
    }
  3. 位操作判断奇偶数

    • 只要根据数的最后一位是 0 还是 1 来决定即可,为 0 就是偶数,为 1 就是奇数
    if(0 == (n&1)) // 偶数
  4. 位操作交换符号

    • 交换符号将正数变成负数,负数变成正数
    let n = -8
    ~n + 1 // => 8
    
    let n = 8
    ~n + 1 // => -8
  5. 位操作求绝对值

    • 整数的绝对值是其本身,负数的绝对值正好可以对其进行取反加 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)
    }

_____
56 声望0 粉丝