一、使用左移运算符 << 迅速得出2的次方,使用右移运算符 >> 迅速除以2的次方
1<<2 // 1*2^2=4 1<<3 // 1*2^3=8 2<<2 // 2*2^2=8 8>>1 // 8/(2^1)=4 8>>2 // 8/(2^2)=2 16>>2 // 16/(2^2)=4
二、使用 ^(按位异或) 切换变量 0 和 1
- 异或即相同为0,不同为1
let toggle = 0; // if 判断 if (toggle) { toggle = 0; } else { toggle = 1; } // 三目运算符 toggle = toggle ? 0 : 1; // 异或 toggle ^= 1;
三、使用&(按位与)判断奇偶性
- 偶数 & 1 = 0
- 奇数 & 1 = 1
8&1 //0 7&1 //1
- 偶数的二进制末尾为0,基数的二进制末尾为1。
四、使用 !! 将数字转为布尔值
- 所有非0的值都是true,包括负数、浮点数
!!7 //true !!1.111 //true !!-1 //true !!0 //false
五、使用~、>>、<<、>>>(带符号位右移)、|来取整
-
~(按位反)、>>(右移)、<<(左移)、>>>(带符号位右移)、|(按位或)
-
相当于使用了 Math.floor()
-
~是按位取反运算,~~是取反两次。 ~~的作用是去掉小数部分
-
位运算都会转整数,注意 >>> 不可对负数取整
~~11.71 //11 11.71 >> 0 //11 11.71 << 0 //11 11.71 | 0 //11 11.71 >>> 0 //11
六、使用^(按位异或)来完成值交换
let a = 7 let b = 1 a ^= b b ^= a a ^= b // 还可以通过加减运算 let a = 7 let b = 1 a = a + b; b = a - b; a = a - b; // ES6,解构赋值 [a, b] = [b, a];
七、使用^(按位异或)判断符号是否相同
- (a ^ b) >= 0; // true 相同; false 不相同
//符号不同 let a = 1 let b = -1 a ^ b //符号相同 let a = 1 let b = 1 a ^ b //符号相同 let a = 1 let b = 2 a ^ b
八、使用^(按位异或)来检查数字是否不相等
-
(a ^ b) === 0; // true 相等; false 不相等
let a = 10 let b = 10 a ^ b
九、n & (n - 1),如果为 0,说明 n 是 2 的整数幂
-
2的整数幂二进制最高位为1,其余位为0。比如8:1000
- 2的整数幂减1的最高位为0,其余位为1。比如7:0111
let a = 4 a & ( a - 1 ) let a = 3 a & ( a - 1 )
十、使用 A + 0.5 | 0 来替代 Math.round()
let a = 2.15 a + 0.5 | 0 let a = 2.87 a + 0.5 | 0
- 如果是负数,只需要-0.5
let a = -2.15 a - 0.5 | 0 let a = -2.87 a - 0.5 | 0
补充:0.1 + 0.2 的结果是 0.30000000000000004
-
JavaScript中数字的存储标准是 IEEE754 浮点数标准。代码中使用的无论是整数还是小数,都是同一种数据类型——64 位双精度浮点型。
-
所有数字以二进制存储,每个数字对应的二进制分为三段:符号位、指数位、尾数位。
-
于存储的二进制有 64 位,其中符号位在六十四位的第一位,0 表示正数,1 表示负数。符号位之后的 11 位是指数位,决定了数字的范围。指数位之后的 52 位是尾数位,决定了数字的精度。
-
0.1 和 0.2 用二进制表示时为 0.0001 1001 1001 1001...(1100循环) 和 0.0011 0011 0011 0011...(0011循环)。如果截取于第 52 位,就会得到一个有误差的结果。