位运算

2021-02-21  本文已影响0人  bowen_wu

概述

按位操作符(Bitwise operators) 将其操作数(operands)当作32位的比特序列(由0和1组成),而不是十进制、十六进制或八进制数值。例如,十进制数9,用二进制表示则为1001。按位操作符操作数字的二进制形式,但是返回值依然是标准的JavaScript数值。

按位操作符

有符号 32 位整数

  1. 二进制编码

    // 其中 0b 代表二进制
     314 (base 10) = 0b00000000000000000000000100111010 (base 2)
    
  2. 反码

     314 (base 10) = 0b00000000000000000000000100111010 (base 2)
    ~314 (base 10) = 0b11111111111111111111111011000101 (base 2)
    
  3. 补码

     314 (base 10)  = 0b00000000000000000000000100111010 (base 2)
    ~314 (base 10)  = 0b11111111111111111111111011000101 (base 2)
    // -314 = 314 反码 + 1
    -314 (base 10)  = 0b11111111111111111111111011000110 (base 2)
    
  4. 符号位
    补码保证了当一个数是正数时,其最左的比特位是0,当一个数是负数时,其最左的比特位是1。因此,最左边的比特位被称为符号位

  5. 特殊数字

     0 (base 10) = 00000000000000000000000000000000 (base 2)
    -1 (base 10) = 11111111111111111111111111111111 (base 2)
    

按位逻辑操作符

从概念上讲,按位逻辑操作符按遵守下面规则:

& (按位与)

a b a & b
0 0 0
0 1 0
1 0 0
1 1 1
     9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)

注意:

| (按位或)

a b a 或 b
0 0 0
0 1 1
1 0 1
1 1 1
     9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)

注意:

~ (按位非)

a ~a
0 1
1 0
 9 (base 10) = 00000000000000000000000000001001 (base 2)
               --------------------------------
~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)

注意:

^ (按位异或)

a b a ^ b
0 0 0
0 1 1
1 0 1
1 1 0
     9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)

注意:

标志位与掩码

标志位

位运算经常被用来创建、处理以及读取标志位序列——一种类似二进制的变量。标志位序列可以节省内存

例如,有 4 个标志位:

标志位通过位序列 DCBA 来表示

例如:一个变量 flags 的二进制值为 0101:

const flags = 0b0101;

这个值表示:

掩码

掩码 (bitmask) 是一个通过与 | 或来读取标志位的位序列。典型的定义每个标志位的原语掩码如下:

const flag_A = 0b0001;
const flag_B = 0b0010;
const flag_C = 0b0100;
const flag_D = 0b1000;

新的掩码可以在以上掩码上使用逻辑运算创建。

应用:

德摩根定律

~(a & b) === ~a | ~b
~(a | b) === ~a & ~b

实用技能

~ + indexOf


const str = 'rawr';
const searchFor = 'a';

// ~-1 === 0
if (~str.indexOf(searchFor)) {
  // searchFor 包含在字符串中
} else {
  // searchFor 不包含在字符串中
}

// (~str.indexOf(searchFor))的返回值
// r == -1
// a == -2
// w == -3

通过某个条件来切换一个值为0或者1

let whether = false;
let number = 1;

// whether === true  => num === 0
// whether === false => num === 1
num = whether ^ 1;

// number 在 0 和 1 之间切换
number ^= 1;

判断奇偶

if(a & 1) {
  // 奇数
} else {
   // 偶数
}
上一篇 下一篇

猜你喜欢

热点阅读