位运算符全面介绍(2)

//分析如下 25 = 0000 0000 0000 0000 0000 0000 0001 1001 3 = 0000 0000 0000 0000 0000 0000 0000 0011 --------------------------------------------- XOR = 0000 0000 0000 0000 0000 0000 0001 1010

“异或运算”有一个特殊运用,连续对两个数a和b进行三次异或运算,aˆ=b, bˆ=a, aˆ=b,可以互换它们的值。这意味着,使用“异或运算”可以在不引入临时变量的前提下,互换两个变量的值

var a=10,b=9; a ^= b, b ^= a, a ^= b; console.log(a,b);//9,10

//分析如下 a = 0000 0000 0000 0000 0000 0000 0000 1010 b = 0000 0000 0000 0000 0000 0000 0000 1001 --------------------------------------------- a1 = 0000 0000 0000 0000 0000 0000 0000 0011 a1 = 0000 0000 0000 0000 0000 0000 0000 0011 b = 0000 0000 0000 0000 0000 0000 0000 1001 --------------------------------------------- b1 = 0000 0000 0000 0000 0000 0000 0000 1010 b1 = 0000 0000 0000 0000 0000 0000 0000 1010 a1 = 0000 0000 0000 0000 0000 0000 0000 0011 --------------------------------------------- a2 = 0000 0000 0000 0000 0000 0000 0000 1001 //a=a2=10;b=b1=9

一个整数与0按位异或可以保持其自身,一个小数与0按位异或可以取整

console.log(3.1 ^ 0);//3 console.log(3.9 ^ 0);//3

左移  

左移操作符由两个小于号(<<)表示,这个操作符会将数值的所有位向左移动指定的位数

例如,如果将数值2(二进制码为10)向左移动5位,结果就是64(1000000)

位运算符全面介绍

var oldValue = 2; var newValue = oldValue<<5; console.log(newValue);//64

左移不会影响操作数的符号位。换句话说,如果将-2向左移动5位,结果将是-64

var oldValue = -2; var newValue = oldValue<<5; console.log(newValue);//-64

左移0位可以实现取整效果

console.log(3.1 << 0);//3 console.log(3.9 << 0);//3

有符号右移  

有符号的右移操作符由两个大于号(>>)表示,这个操作符会将数值向右移动,但保留符号位(即正负号标记)。有符号的右移操作与左移操作正好相反,即如果将64向右移动5位,结果将变回2

var oldValue = 64; var newValue = oldValue>>5; console.log(newValue);//2

同样,在移位过程中,原数值中也会出现空位。只不过这次的空位出现在原数值的左侧、符号位的右侧。而此时ECMAScript会用符号位的值来填充所有空位,以便得到一个完整的值

右移可以模拟2的整除运算

console.log(5>>1);//2 console.log(15>>1);//7

无符号右移  

无符号右移操作符由3个大于号(>>>)表示,这个操作符会将数值的所有32位都向右移动。对正数来说,无符号右移的结果与有符号右移相同。仍以前面有符号右移为便,如果将64无符号右移5位,结果仍然是2

var oldValue = 64; var newValue = oldValue>>>5; console.log(newValue);//2

但是,对负数就不一样了。首先,无符号右移是以0来填充空位,而不是像有符号右移那样以符号位的值来填充空位。所以,对正数的无符号右移与有称号右移结果相同,但对负数的结果就不同了。其次,无符号右移操作符会把负数的二进制码当成正数的二进制码。而且,由于负数以其绝对值的二进制补码形式表示,因此就会导致无符号右移后的结果非常之大

var oldValue = -64; var newValue = oldValue>>>5; console.log(newValue)//134217726

要确定-64的二进制表示,首先必须得到64的二进制表示,如下所示:

0000 0000 0000 0000 0000 0000 0100 0000

接下来,计算二进制反码,如下所示:

1111 1111 1111 1111 1111 1111 1011 1111

最后,在二进制反码上加 1,如下所示

1111 1111 1111 1111 1111 1111 1011 1111 1 --------------------------------------- 1111 1111 1111 1111 1111 1111 1100 0000

向右移动5位后,如下所示:

0000 0111 1111 1111 1111 1111 1111 1110 console.log(0b00000111111111111111111111111110);//134217726

常见应用

【1】乘法运算

利用左移(<<)来实现乘法运算

console.log(2 << 1);//4 console.log(3 << 1);//6 console.log(4 << 1);//8

【2】除法运算

利用有符号右移(>>)来模拟2的整除运算

console.log(2 >> 1);//1 console.log(5 >> 1);//2 console.log(8 >> 1);//4 console.log(9 >> 1);//4

【3】值互换

利用异或操作(^)可以实现值互换的效果

var a=10,b=9; a ^= b, b ^= a, a ^= b; console.log(a,b);//9,10

【4】小数取整

利用取两次按位非、与0按位或、与0按位异或、左移0位、右移0位都可以实现小数取整效果

console.log(~~3.1);//3 console.log(3.1|0);//3 console.log(3.1^0);//3 console.log(3.1<<0);//3 console.log(3.1>>0);//3

【5】开关

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzswxs.html