|234 = 251
"00000000000000000000000001111011"
"00000000000000000000000011101010"
---------------------------------------------
"00000000000000000000000011111011"
按位异或(^):两个数的相同位,一个是 1 另一个是 0 则返回 1,否则返回0
复制代码 代码如下:
^234 = 145
"00000000000000000000000001111011"
"00000000000000000000000011101010"
---------------------------------------------
"00000000000000000000000010010001"
异或运算的一些特性:
复制代码 代码如下:
a ^ a = 0
a ^ b = b ^ a
a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c
a ^ b ^ a = b
d = a ^ b ^ c 可以推出 a = d ^ b ^ c //这个特性被用在一些加密算法中
//如果运算数在适当范围内(不溢出), 如 a=1,b=2,交换两个变量的值
a = [b,b=a][0]
//或者
a = a^b
b = a^b
a= a^b
利用位的异或运算使用一个数字记录多个信息:
有几个状态值分别是 1、2、8、16 .....
这些值的规律是,他们的二进制只有一位是 1 ,其余都是 0, 因此, 他们中的任意几个的按位异或运算的结果都不会出现 两个数的某一位都是 1 的情况,并且运算的值都是唯一确定的,也就是,知道运算的结果,就知道是哪几个数的组合,这样可以用一个数字记录多个信息。
复制代码 代码如下:
00000001
00000010
00000100
00001000
00010000
1^2^4 = 7 // "00000111"
因此,如果我们知道结果是 7 ,就知道他们是由 1 、2、4 组合而成。
如果我们要设置一个参数,使其包含几个状态值,就可以用 按位或运算,
这样的例子可以参考 PHP 中关于图片类型的几个常量,和 PHP 错误等级定义的几个常量。
这样的例子,也许有用十进制数来描述的,比如: 个位数的数字表示某个属性的状态,十位数的数字表示另一个属性的状态,这样的话,每个状态可以有 10 个值,只用一个数字就可以描述的组合非常多。
左移位(<<) : 一个数的二进制所有位向左移动,符号位不动,高位溢出丢弃,低位补 0
如果不溢出, 左移位的效果是乘以 2。
右移位(>>): 一个数的二进制所有位向右移动,符号位不动,高位补0,低位丢弃
右移位操作的效果是除以 2 并向下取整。
带符号右移(>>>):移位时符号位跟随移动,符号位也作为数值看待,所以,该操作的结果是 32 位无符号整数,因此负数的带符号右移将产生正整数,正数的带符号右移与 无符号右移相同,这是唯一可以操作符号位的运算。
-123>>>1 ;//2147483586
一些要注意的地方:
位运算必须是整数,如果运算元不是可用的整数,将取 0 作为运算元
复制代码 代码如下:
~NaN; // 将执行 ~0 ,结果为 -1
~'x'; // -1
'hello'|0; // 0
({})|0 ; //0
位移运算不能移动超过31位,如果试图移动超过31位,将位数 对32取模后再移位
123>>32 //实际是 123>>0 (32%32 = 0)
123>>33 //实际是 123>>1
32位带符号整数表达范围是 -Math.pow(2,31) ~ Math.pow(2,31)-1 即 -2147483648~2147483647,而 js 数字的精度是双精度,64位,如果一个超过 2147483647 的整数参与位运算的时候就需要注意,其二进制溢出了,截取32位后,如果第32位是1将被解读为负数(补码)。
复制代码 代码如下:
>>0; //-2147483648
>>0; //0
>>0; //-1
>>0; //1
您可能感兴趣的文章: