基础点
位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。
对于有符号的整数,32位中的前31位用于表示整数的值。第32位用于表示数值的符号:0表示正数,1表示负数。
这个表示符号的位叫做符号位。例如,数值18的二进制表示是00000000000000000000000000010010,或者更简洁的10010。
位运算------》常规
因为 js 的整数默认是带符号正数,所以在为运算中,只能使用 31 位(0~2147483647),开发者是不能访问最高位的。
位运算只发生在整数上,因此一个非浮点数参与位运算之前会被向下取整。
按位与(&):两个数的相同位,都是 1 返回1 ,否则返回0
123&234 = 106
123 "00000000000000000000000001111011"
234 "00000000000000000000000011101010"
106 "00000000000000000000000001101010"
按位或(|):两个数的相同位,有一个是 1 则返回 1 ,否则返回 0
123|234 = 251
123 "00000000000000000000000001111011"
234 "00000000000000000000000011101010"
---------------------------------------------
251 "00000000000000000000000011111011"
按位异或(^):两个数的相同位,一个是 1 另一个是 0 则返回 1,否则返回0
123^234 = 145
123 "00000000000000000000000001111011"
234 "00000000000000000000000011101010"
---------------------------------------------
145 "00000000000000000000000010010001"
左移位(<<) : 一个数的二进制所有位向左移动,符号位不动,高位溢出丢弃,低位补 0
如果不溢出, 左移位的效果是乘以 2。
右移位(>>): 一个数的二进制所有位向右移动,符号位不动,高位补0,低位丢弃
右移位操作的效果是除以 2 并向下取整。
位运算------》使用举例
一些要注意的地方:
位运算必须是整数,如果运算元不是可用的整数,将取 0 作为运算元
对浮点数向下求整,我们会用下面的方法:
varnum =Math.floor(1.1);// 1
我们也可以用位运算来求整:
varnum=1.1|0;// 1
其实浮点数是不支持位运算的,所以会先把1.1转成整数1再进行位运算,就好像是对浮点数向下求整。所以1|0的结果就是1。
判断一个数是奇数还是偶数,我们会用求余数来判断:
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是奇数"
有符号左移(<<)
有符号左移会将32位二进制数的所有位向左移动指定位数。如:
varnum=2;// 二进制10num=num<<5;// 二进制1000000,十进制64
如果要求2的n次方,可以这样:
functionpower(n){return1<< n;}power(5);// 32
1的二进制是01,左移5位就是0100000,十进制就是2的5次方32。
有符号右移(>>)
有符号右移会将32位二进制数的所有位向右移动指定位数。如:
varnum=64;// 二进制1000000num=num>>5;// 二进制10,十进制2
求一个数的二分之一:
var num =64>> 1;//32
有符号左移与右移不会影响符号位。
无符号右移(>>>)
正数的无符号右移与有符号右移结果是一样的。负数的无符号右移会把符号位也一起移动,而且无符号右移会把负数的二进制码当成正数的二进制码:
varnum=-64;// 11111111111111111111111111000000num=num>>>5;// 134217726
所以,我们可以利用无符号右移来判断一个数的正负:
functionisPos(n){return(n === (n >>>0)) ?true:false; }isPos(-1);// falseisPos(1);// true
~: 取反
相当于:数字求负,在减1
1的 取 反----》结果是-2
一眼练习:
//按位与&:两个操作数都是1,结果才是1
alert(a&b) //结果是0
//按位或:两个操作数只要有一个是1,结果就是1
alert(a|b) //结果是1
//按位异或:两个数字一样,结果为0;两个数字不一样,结果就是1。
alert(a^b) //结果是1
//简单的方法:数字求负,在减1
alert(~a)//结果是-2
有符号左移(<<)
有符号左移会将32位二进制数的所有位向左移动指定位数。如:
varnum=2;// 二进制10num=num<<5;// 二进制1000000,十进制64
如果要求2的n次方,可以这样:
functionpower(n){return1<< n;}power(5);// 32
1的二进制是01,左移5位就是0100000,十进制就是2的5次方32。
有符号右移(>>)
有符号右移会将32位二进制数的所有位向右移动指定位数。如:
varnum=64;// 二进制1000000num=num>>5;// 二进制10,十进制2
求一个数的二分之一:
var num =64>> 1;//32
有符号左移与右移不会影响符号位。
无符号右移(>>>)
正数的无符号右移与有符号右移结果是一样的。负数的无符号右移会把符号位也一起移动,而且无符号右移会把负数的二进制码当成正数的二进制码:
varnum=-64;// 11111111111111111111111111000000num=num>>>5;// 134217726
所以,我们可以利用无符号右移来判断一个数的正负:
functionisPos(n){return(n === (n >>>0)) ?true:false; }isPos(-1);// falseisPos(1);// true
JS常用的进制转换方法:
十进制转换为二进制:
语法
NumberObject.toString(radix);
其中,radix为可选。规定表示数字的基数,使 2 ~ 36 之间的整数。若省略该参数,则使用基数 10。但是要注意,如果该参数是 10 以外的其他值,则 ECMAScript 标准允许实现返回任意值。
toString()方法可把一个 Number 对象转换为一个字符串,并返回结果。
二进制转十进制:
parseInt(string, radix);
其中,string为必需。要被解析的字符串。radix为可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则parseInt() 将返回 NaN。
返回值
返回解析后的数字。
当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。
举例,如果 string 以 "0x" 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。如果 string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。
parseInt() 函数可解析一个字符串,并返回一个整数。