位运算符是一种对数字转化成32位二进制整数值进行运算的运算符(js里的加减等基本运算则是按双精度的浮点数来运算),那么:
100.03^0 // 100
100^0 // 100
因为是对数字的二进制形式直接进行运算,其效率一般都优于常规的运算。所以,项目中在保证基本正确性的前提下能尽其所能的运用位运算符操作,既能让代码表现的高大上一些,还能很好地提高部分运算的效率。
下面,就我所了解的几个位运算符的原理及用法进行下说明,供参考。
首先介绍一个将10进制数字值转化为N进制数字值的办法:
// num为10进制数,t为要转化成的进制数
function trans(num,t){
if(t<2 || t>36){
throw 'RangeError: toString() radix argument must be between 2 and 36';
}
return +num.toString(t);
}
为什么num前面要加一个+号呢?你可以试试调用3.toString(2);,是的,会报错。你再试试3..toString(2);,是的没错,是有两个点操作符,很奇怪的语法却能正确运行了!或者,你试下Number(3).toString(2);或者(3).toString(2),也是可以的。
一切都是为什么呢?
在Javascript中,数字都是双精度的浮点数,如果一个整数数字后面跟着一个.符号,它会认为是浮点数的小数点而不会认为是属性操作符。所以3.toString(2)的格式就会报错了。而其他情况下则都会认为.符号为属性操作符。
1、~位运算符
原理:
~是对位求反 1变0, 0变1。
~num的运算相当于:-num-1
function test(num){return (~num) === -num-1}
注意到~-1是为0的,我们可以用在“判断一个基本类型数据值是否位于某一数组”中。不管是数组原生的方法indexOf()(如果存在该方法的话),还是jQuery的$.inArray()、unders的_.indexOf()方法,如果某个值不在数组中返回值都是-1,而!!-1结果是为true的。假设值不位于数组中的时候为false,我们可以用~[0].indexOf(1)、~$.inArray(1,[0])、~_.indexOf([0],1)来做判断。当然常规的_.indexOf([0],1)<0来做判断也是可以的。
2、>>移位运算符
原理:
移位运算符把位按指定的值向左或向右移动
<< 向左移动而 >> 向右移动,超过的位将丢失,而空出的位则补0
如 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1(十进制16387) 向左移动两位将变成
0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 (十进制12)
向右移动两位则是
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0(十进制4096)
<< 向左移动而 >> 向右移动,超过的位将丢失,而空出的位则补0
如 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1(十进制16387) 向左移动两位将变成
0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 (十进制12)
向右移动两位则是
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0(十进制4096)
num>>1的运算相当于:Math.floor(num/2)
function test(n){return n>>1 === Math.floor(n/2);}
此种情形我们一般都用在循环中让循环的次数减半来提高运算效率。如下面的这个需求:
实现一个repeat()方法,来获取指定参数重复指定次数的字符串(或数组)。实现如下:
function repeat(target,n){
var s = target,
total = '';
while(n > 0){
if(n %2 ==1){
total += s;
}
if(n ==1){
break;
}
s += s;
n = n>>1;// 相当于Math.floor(n/2)
}
return total;
}
效率还是很高的。
>>位运算符还有一个常见的用法就是用来将数字取整,如下:
任何小数num把num>> 0可以取整
如3.14159 >> 0 === 3;
如3.14159 >> 0 === 3;
3、^位运算符
原理:按位异或
例如:
0111001
1010010
按位异或的结果就是:1101011
它有一个神奇的特性:
var n1 = 3;
var n2 = 4;
n1 ^= n2;
n2 ^= n1;
n1 ^= n2;
这样你会发现n1 = 4, n2=3,n1,n2在不使用任何中间变量的情况下交换了值,所有的整数都适用这种情况。
暂时想到的就这么多,后续有新的发现再继续往上添加。