JavaScript 二进制笔记

位运算

JavaScript 中的位运算是将操作数视为 32 位元的二进制串,返回标准的 JavaScript 数值。

JavaScript 中数值都由 64 位浮点数存储,但在两个整数进行位运算时,会转化为 32 位的有符号整数。

所以在计算机中,数字是有穷的,在 JavaScript 中也是有穷的。

所以有一个安全数的概念。所谓安全数就是在这个范围内都存在一正一反一一对应。

JavaScript 的安全数在 ES6 中是 Number.MAX_SAFE_INTEGER。

但位运算只针对 32 位整数。对于浮点小数会先转化为 32 位的二进制串,在进行计算。

位运算符

Operator Usage 位运算符
按位与 ADD a & b a 和 b 对应位都为 1 则返回 1,否则返回0
按位或 OR a b
按位异或 XOR a ^ b a 和 b 对应位相同返回 1,否则返回 0
按位非 NOT ~a a 中每一位取反
左移 shift a << b 将 a 的二进制串向左移动 b 位,右边填充 0
算术右移 a >> b 将 a 的二进制串向右移动 b 位,丢弃移出的所有位
无符号右移 a >>> b 将 a 的二进制串向右移动 b 位,丢弃移出的所有位,并把左边空出的位用 0 填充

位运算技巧

左移 & 右移

左移以为相当于乘于二,右移一位相当于除于二并向下取整(不是向 0 取整)。

let a = 2
console.log(a << 2) // 8 = 2 * 2 * 2

console.log(a >> 2) // 0 = Math.floor(2 / 2 / 2)
复制代码

异或

异或运算有两种理解方式

  1. 相同为 1,不同为 0
  2. 不进位相加

异或运算满足交换律和结合率

0 异或任何数都为该数本身,一个数异或它自己为 0

let a = 8
console.log(a ^ a) // 0
console.log(a ^ 0) // 8
复制代码

通过异或还可以实现不使用额外空间交换值

let a = 8
let b = 7
a = a ^ b
b = a ^ b
a = a ^ b

console.log(a, b) // 7, 8
复制代码

但是这个方法有一个限制,a , b 的内存地址必须保证不一样,否则会返回 0

提取最右侧的 1


let a = 9
let rightOne = a & (~a + 1)
console.log(parseInt(a).toString(2), parseInt(rightOne).toString(2)); // 1001 1
复制代码

获取一个数二进制的某一位

// 获取 a 的第 b 位,最低位为 0
function getBit(a, b) {
    return (a >> b) & 1
}
console.log(parseInt(getBit(15, 2)).toString(2)); // 1
复制代码

将一个二进制数的某一位设置为 0

// 将 a 的第 b 位设置为 0 ,最低位编号为 0
function unsetBit(a, b) {
    return a & ~(1 << b)
}
复制代码

将一个二进制数某一位设置为 1

// 将 a 的第 b 位设置为 1 ,最低位编号为 0
function setBit(a, b) {
    return a | (1 << b)
}
复制代码

将一个二进制某一位取反

// 将 a 的第 b 位取反 ,最低位编号为 0
function flapBit(a, b) {
    return a ^ (1 << b)
}
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享