js中位运算的运用实例分析
我们可能很少在编程中用位运算,如果没深入学习,可能也很难理解。平时的数值运算,其实是要先转换成二进制再进行运算的,而位运算就是直接进行二进制运算,所以位运算的执行效率肯定是更高的。下面通过一些实例来加深对位运算的理解。
按位与(&)
&&运算符我们都知道,只有两个都为真,结果才为真。&道理是一样的,只有两个数的值为1时,才返回1。例如1和3的按位与操作:
0001
& 0011
---------
0001
只有对应的数为1时,结果才为1,其他都为0。
判断一个数是奇数还是偶数,我们会用求余数来判断:
functionassert(n){ if(n%2===1){ console.log("n是奇数"); }else{ console.log("n是偶数"); } } assert(3);//"n是奇数"
我们也可以用一个数和1进行按位&操作来判断,而且速度更快:
functionassert(n){ if(n&1){ console.log("n是奇数"); }else{ console.log("n是偶数"); } } assert(3);//"n是奇数"
下面是位运算过程:
1=0001
3=0011
--------
& =0001
奇数的二进制码的最后一位数肯定是1,而1只有最后一位为1,按位&操作之后,结果肯定只有最后一位数为1。而偶数的二进制表示的最后一位数是0,和1进行按位&操作,结果所有位数都为0。
按位或(|)
|与||操作符的道理也是一样的,只要两个数中有一个数为1,结果就为1,其他则为0。
0001
|0011
---------
0011
对浮点数向下求整,我们会用下面的方法:
varnum=Math.floor(1.1);//1
我们也可以用位运算来求整:
varnum=1.1|0;//1
其实浮点数是不支持位运算的,所以会先把1.1转成整数1再进行位运算,就好像是对浮点数向下求整。所以1|0的结果就是1。
按位非(~)
按位非就是求二进制的反码:
varnum=1;//二进制00000000000000000000000000000001
varnum1=~num;//二进制11111111111111111111111111111110
我们知道,js中的数字默认是有符号的。有符号的32位二进制的最高位也就是第一位数字代表着正负,1代表负数,0代表整数。那到底11111111111111111111111111111110等于多少呢?最高位为1代表负数,负数的二进制转化为十进制:符号位不变,其他位取反加1。取反之后为10000000000000000000000000000001,加1之后为10000000000000000000000000000010,十进制为-2。
按位异或(^)
按位异或是两个数中只有一个1时返回1,其他情况返回0。
0001
^0011
---------
0010
数字与数字本身按位异或操作得到的是0,因为每两个对应的数字都相同,所以最后返回的都是0。
我们经常会需要调换两个数字的值:
varnum1=1,num2=2,temp; temp=num1; num1=num2;//2 num2=temp;//1
如果装逼一点的话,可以这样:
varnum1=1,num2=2; num1=[num2,num2=num1][0]; console.log(num1);//2 console.log(num2);//1
如果想再装的稳一点的话,可以这样:
varnum1=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位二进制数的所有位向左移动指定位数。如:
varnum=2;//二进制10
num=num<<5;//二进制1000000,十进制64
如果要求2的n次方,可以这样:
functionpower(n){ return1<1的二进制是01,左移5位就是0100000,十进制就是2的5次方32。
有符号右移(>>)
有符号右移会将32位二进制数的所有位向右移动指定位数。如:
varnum=64;//二进制1000000
num=num>>5;//二进制10,十进制2求一个数的二分之一:
varnum=64>>1;//32
有符号左移与右移不会影响符号位。
无符号右移(>>>)
正数的无符号右移与有符号右移结果是一样的。负数的无符号右移会把符号位也一起移动,而且无符号右移会把负数的二进制码当成正数的二进制码:
varnum=-64;//11111111111111111111111111000000
num=num>>>5;//134217726所以,我们可以利用无符号右移来判断一个数的正负:
functionisPos(n){ return(n===(n>>>0))?true:false; } isPos(-1);//false isPos(1);//true-1>>>0虽然没有向右移动位数,但-1的二进制码已经变成了正数的二进制码:
11111111111111111111111111111111
所以-1>>>0的值为4294967295。
总结
以上的例子在平常可能会比较容易用到或看到,也是属于比较容易理解的。一些比较复杂的、难理解的,我觉得应该尽量少用,因为会给阅读者带来困难,也会给自己带来麻烦。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。