JavaScript 位运算符 at 2009.10.15 22:10
JavaScript 在日常的应用中非常的少,其实当年在大学学习C#的时候,位运算符也不是重点,而且后来考试的时候根本就没有考这章,但是对于对数字感兴趣的我,当时听的特认真,以至于虽然从来都没再看过,印象还是非常的深刻,前几天在用的时候进入了个误区,所以这里还是记录一下,巩固一下哈~
JavaScript 的位运算符一共有7个,分别是&、|、^、~、<<、>>、>>>(C#没有这个运算符,但是C#可以通过>>的逻辑右移来实现此运算),位运算的操作都是通过二进制进行的。
按位与运算符(&)
当两个数相同位都为1时返回1,否则返回0,例如1&2=0,1的二进制表示为0001,2的二进制表示为0010,二者的运算则返回0000。
按位或运算符(|)
当两个数相同位数字不同的时候返回1,否则返回0,例如1|2=3。
按位异或运算符(^)
当两个数相同位仅有一个为1的时候返回1,否则返回0,例如1^2=3。
按位非运算符(~)
~是一个一元运算符,它将所有位数取反。这里首先必须要说下负数的存储,负数是以其正数的二进制补码进行存储的,所以我们在进行负数的运算时,必须要正确的获取其二进制编码,也就是其正数的二进制补码。补码是取反然后加1来实现,下面看例子:
先计算3的反码:3的二进制形式为00000011,其反码为11111100,其补码为11111101,所以-3的二进制编码为11111101,那么我们要求~-3,就是取其反码,为00000010,这就是-3的反码,将其转化为十进制为2。
多试几个就会发现,其实一个数的反码就是其十进制的相反数减去1。
左移运算符(<<)
左移运算符就是将数的所有位集体左移,第一位变成第二位,第二位变成第三位。。。空出的新位用0补充。比如1<<2=4,-1<<2=-4。1的二进制表示为0000 0001,那么将其向左移动两位变成了0000 0100,转换为十进制就为4,-1的二进制表示为1111 1111,将其向左移动两位,得到1111 1100,1开头的为负数,将其转化为十进制则需要倒着执行一次补码的计算,就是先减去1,得到1111 1011,然后取反,得到0000 0100,转化为十进制加负号得到4。这里需要注意下二进制的减法运算法则:1-1=0-0=0,1-0=1,0-1=1(向高位借)。
这里我们可以发现左移运算就是将其十进制数乘以2的位数次方。
带符号的右移运算符(>>)
既然左移是乘以2,那么右移肯定应该是除以2了,事实上就是这样子的,如果数字本身为正数,则在高位补0,如果为负数则在高位补1。例如3>>1=1,-3>>1=-2。3的二进制编码表示为0000 0011,将其向右移动1位,得到0000 0001,转换为十进制就是1,-3的二进制编码为1111 1101,将其向右移动1位得到1111 1110,这是一个负数,负数转化为十进制,先减一得到1111 1101,取反为0000 0010,得到-2。
带符号的右移运算就是将其十进制数除以2的位数次方,并舍弃余数。
无符号的右移运算符(>>>)
正数的无符号右移运算结果跟带符号的右移运算是一样的,主要是负数的无符号右移运算。它跟带符号的右移的区别就在于,不管是正数还是负数,高位都以0补充,所以对正数来说带符号和无符号的运算都是一样的,而对于负数来说则是天壤之别。例如:-1>>>1=2147483647,数字很恐怖是吧,看看计算过程:-1的二进制编码为1111 1111 1111 1111 1111 1111 1111 1111,将其右移1位,并补0,得到0111 1111 1111 1111 1111 1111 1111 1111,第一位为0,是正数,将其转化为十进制就是230+229+……+20=230(1-1/231)/(1-1/2)=231-1=2147483647,这样最终得到了我们需要的结果,结果很恐怖,慎用!
位运算符的应用: