js位运算相关内容

12 篇文章 0 订阅

位运算是直接进行二进制运算,所以位运算的执行效率是更高的,可以在项目中优先使用

按位与(&)

&&运算符我们都知道,只有两个都为真,结果才为真。&道理是一样的,只有两个数的值为1时,才返回1。例如1和3的按位与操作:

                    0101
                 &  0011
                ---------
                    0001

只有对应的数为1时,结果才为1,其它都为0。
判断一个数是奇数还是偶数,我们会用求余数来判断:

function assert(n) {
  if (n % 2 === 1) {
    console.log("n是奇数")
  } else {
    console.log("n是偶数")
  }
}

assert(3) // "n是奇数"

我们也可以用一个数和1进行按位&操作来判断,而且速度更快:

function assert(n) {
  if (n & 1) {
    console.log("n是奇数")
  } else {
    console.log("n是偶数")
  }
}

assert(2) // "n是偶数"

下面是位运算过程:

                 4 = 0100
                 1 = 0001
                 --------
                 & = 0000

奇数的二进制码的最后一位数肯定是1,而1只有最后一位为1,按位&操作之后,结果肯定只有最后一位数为1。而偶数的二进制表示的最后一位数是0,和1进行按位&操作,结果所有位数都为0。

按位或(|)

|与||操作符的道理也是一样的,只要两个数中有一个数为1,结果就为1,其他则为0。

                    0001
                 |  0011
                ---------
                    0011

对浮点数向下求整,我们会用下面的方法:

var num = Math.floor(1.1) // 1

我们也可以用位运算来求整:

var num = 1.1 | 0 // 1

其实浮点数是不支持位运算的,所以会先把1.1转成整数1再进行位运算,就好像是对浮点数向下求整。所以1|0的结果就是1。

按位非(~)

按位非就是求二进制的反码:

var num = 1 // 二进制 00000000000000000000000000000001
var num1 = ~num // 二进制 11111111111111111111111111111110

我们知道,js中的数字默认是有符号的。有符号的32位二进制的最高位也就是第一位数字代表着正负,1代表负数,0代表整数。那到底11111111111111111111111111111110等于多少呢?最高位为1代表负数,负数的二进制转化为十进制:符号位不变,其他位取反加1。取反之后为10000000000000000000000000000001,加1之后为10000000000000000000000000000010,十进制为-2。正数按位非的值为本身加一变为负数。

按位异或(^)

按位异或是两个数中只有一个1时返回1,其他情况返回0。

                    0001
                 ^  0011
                ---------
                    0010

数字与数字本身按位异或操作得到的是0,因为每两个对应的数字都相同,所以最后返回的都是0。

我们经常会需要调换两个数字的值:

var num1 = 1, num2 = 2, temp
temp = num1
num1 = num2 // 2
num2 = temp // 1

如果装逼一点的话,可以这样:

var num1 = 1, num2 = 2
num1 = [num2, num2 = num1][0]
console.log(num1) // 2
console.log(num2) // 1

如果想再装的稳一点的话,可以这样:

var num1 = 1, num2 = 2
num1 ^= num2 // num1 = num1 ^ num2 = 1 ^ 2 = 3
num2 ^= num1 // num2 = num2 ^ (num1 ^ num2) = 2 ^ (1 ^ 2) = 1
num1 ^= num2 // num1 = num1 ^ num2 = 3 ^ 1 = 2
console.log(num1) // 2
console.log(num2) // 1

有符号左移(<<)

有符号左移会将32位二进制数的所有位向左移动指定位数。如:

var num = 2 // 二进制10
num = num << 5 // 二进制1000000,十进制64

如果要求2的n次方,可以这样:

function power(n) {
  return 1 << n
}

power(5) // 32

1的二进制是01,左移5位就是0100000,十进制就是2的5次方32。

有符号右移(>>)

有符号右移会将32位二进制数的所有位向右移动指定位数。如:

var num = 64 // 二进制1000000
num = num >> 5 // 二进制10,十进制2

求一个数的二分之一:

var num = 64 >> 1 // 32

有符号左移与右移不会影响符号位。

无符号右移(>>>)

正数的无符号右移与有符号右移结果是一样的。负数的无符号右移会把符号位也一起移动,而且无符号右移会把负数的二进制码当成正数的二进制码:

var num = -64 // 11111111111111111111111111000000
num = num >>> 5 // 134217726

所以,我们可以利用无符号右移来判断一个数的正负:

function isPos(n) {
  return (n === (n >>> 0)) ? true : false    
}

isPos(-1) // false
isPos(1) // true

-1>>>0虽然没有向右移动位数,但-1的二进制码已经变成了正数的二进制码:

11111111111111111111111111111111 

所以-1>>>0的值为4294967295。

~~用来取整

~~3.5    3

~~-2.6   -2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值