认识位运算

课后整理 2020-12-20

位运算就是对二进制数进行的计算。

位运算是整数的逐位运算。例如,1+1=2,这在十进制计算中是正确的;但是在二进制计算中,1+1= 10;而对于二进制数100去反,则就等于001,而不是-100。

在JavaScript中,位运算要求运算数必须是32位的整数,如果位运算数是非整型,或者大于32位的整数,则将返回NaN。

在默认情况下,所有整数都是带有符号的整数。带有符号的整数中,第1~31位表示整数的值,第32位表示整数的符号,0表示正数,1表示负数。因此整数值的范围为-2147483648~2147483647。

对于正整数来说,它以二进制形式进行存储,第1~31位中每一位都表示2的幂,序数从0开始。第1位表示20,第2位表示21 ,第3位表示22,依此类推。对于没有用到的位使用0来进行填充。例如,对于十进制数值12,使用二进制表示法如图1所示。

图1  12的二进制表示法

其中第1~4位为有效位,如果使用如下方法返回对应的二进制值,可以看到返回值仅是有效位,其他数位由于并不重要,因此就没有返回。

alert((12).toString(2));           // 返回二进制值1100

实际上利用有效位,对于二进制值1100,可以很轻松的使用如下方法转换为十进制值:

(23*1)+(22*1)+(21*0)+(20*0)

=8 + 4 + 0 + 0

= 12

对于负数来说,二进制的存储方式一般采用二进制补码的方式来实现:

第1步,先计算负数对应的正数的二进制值。例如,对于-12,则先计算12的二进制值,如图3所示。

第2步,对第一步中计算的二进制值进行反码。所谓反码就是把位值逐位取反。例如,0取反为1,1取反为0。针对图3所示的12的二进制值反码之后,则如图2所示。

图2  12的二进制值反码

第3步,为二进制反码值加1,如图3所示。

图3  为二进制值反码加1

第4步,最终,-12的二进制值为:11111111111111111111111111110100。

但是如果使用如下方法返回-12的二进制值:

alert((-12).toString(2));            // 返回值-1100

则返回值不是11111111111111111111111111110100,而是-1100,即使用数字绝对值的二进制值加上负号的形式返回。

在处理带有符号的整数时,JavaScript是不允许访问第32位符号位的值。

对于无符号的整数来说,第32位不再是符号位,而是用来表示值,所以它的数值范围为0~4294967295。如果数值小于等于214783647的整数来说,无符号整数与有符号整数表示是一样的,而大于214783647的整数,则第32位为1,此时与有符号整数表示是不一样的。当然,JavaScript所有数值默认都是带有符号位的,只有数值参与到位运算之后,可能生成无符号的整数。