位运算符详解

& (位与运算符)

真真为真,其余为假;

function oddEven(num) {
  let result;
  if(num & 1) {
  // 1 的二进制是 0000 0001, 所以 num & 1 不是 1 就是 0,
  // 奇数的二进制末尾是 1,偶数的二进制末尾是 0
    result = `${num} 为奇数`
  } else {
    result = `${num} 为偶数`
  }
  return result;
}
console.log(oddEven(8)); // 8 为偶数
console.log(oddEven(9)); // 9 为奇数
console.log(oddEven(18));// 18 为偶数
console.log(oddEven(19));// 19 为奇数

| (位或运算符)

假假为假,其余为真;

整数与0的位或运算,都是本身,浮点数不支持位运算,过程中会自动转化成整数,利用这一点,可以将浮点数与0进行位或运算即可达到取整目的。

console.log(15.22 | 0) // 15

~ (位非运算符)

真为假,假为真;

位非运算符有一个规律,值为 - (x + 1);

// ~9  9 二进制位非运算
console.log(~9) // -10
// 0000 0000 0000 0000 0000 0000 0000 1001  // 先转换成32位的二进制
// 1111 1111 1111 1111 1111 1111 1111 0110  // 全部取反
// 1000 0000 0000 0000 0000 0000 0000 1001  // 符号位不变,其余取反
// 1000 0000 0000 0000 0000 0000 0000 1010  // 再加 1; -10

// 可以和indexOf结合使用;
let arr = [1, 2, 3];
// !~arr.indexOf(4) => arr.indexOf(4) == -1; 
if(!~arr.indexOf(4)){ 
// indexOf没找到返回 -1,-1取反为 0, !0 为true,打印 arr 中没有 4
  console.log('arr 中没有 4')
}
if(!!~arr.indexOf(1)){ 
// indexOf找到了返回这个值的下标,返回 0,0取反为-1,!!-1 为true, 打印 arr 中有 1
  console.log('arr 中有 1')
}

^ (异或运算符)

相同为假,不同为真;

// 9 和 10 二进制异或运算
console.log(9^10); // 3
// 1001
// 1010
// ----
// 0011 // 结果为 3
// 实现两个值互换
let a = 3, b = 5;
a ^= b; // a = 3; b = 5; a ^ b = 6;且把值赋给 a   //  0011 ^ 0101 = 0110 = 6
console.log(1, `a=${a}`, `b=${b}`); // a = 6; b = 5;
b ^= a; // a = 6; b = 5; a ^ b = 3; 且把值赋给 b  //   0110 ^ 0101 = 0011 = 3
console.log(2, `a=${a}`, `b=${b}`); // a = 6; b = 3;
a ^= b; // a = 6, b = 3; a ^ b = 5; 且把值赋给 a  //    0110 ^ 0011 = 0101 = 5
console.log(3, `a=${a}`, `b=${b}`); // a = 5; b = 3;

<< (有符号左移)

首位符号不动,把32位二进制数字整体往左边移动指定的位数,左边超出部分舍去,右边补0

console.log(9<<5); // 288
// 0000 0000 0000 0000 0000 0000 0000 0000 1001
// 0000 0000 0000 0000 0000 0000 0001 0010 0000
// 2 的 8 次方 + 2的 5次方  = 256 + 32 = 288
//  可以通过计算公式: num * (2^n), 即 9*Math.pow(2,5)

>> (有符号右移)

首位符号不动,把32位二进制数字整体往右边移动指定位数,右边超出部分被舍去,左边补0。

console.log(288>>5); // 9
// 0000 0000 0000 0000 0000 0000 0001 0010 0000
// 0000 0000 0000 0000 0000 0000 0000 0000 1001
// 可以通过计算公式:num/(2^n),即 288/Math.pow(2,5)

>>> (无符号右移)

符号为也跟着一起移动,这样,无符号右移会把负数的二进制当成整数的二进制码

// 4294967296 >>> 5 = 0; 
// 二进制最大存储的值是 2^32-1;
// 即 0111 1111 1111 1111 1111 1111 1111 1111,最高位为符号位,0表示正,1表示负
// 288>>>5 = 9; 
// 正数的无符号右移和有符号右移值基本一样,除非数值太大二进制存储不下

面试题

let num = 10;
num ^= (1<<4) -1;
console.log(num); // 5
// 1<<4 = 10000 = Math.pow(2,4) = 16
// 16 - 1 = 15
// a ^= 15;  1010 ^ 1111 = 0101 = 5; 并把值赋给 a;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值