本文章主要講解JS中位運算符的基本說明和常見用法
位運算符用于32位的數(shù)字上, 任何的數(shù)字操作都將轉(zhuǎn)為32位, 運算結(jié)果再轉(zhuǎn)化為JS數(shù)字
js包括以下位運算符
- '&': AND運算符
- '|': OR運算符
- '~': 取反
- '^': 異或
- '<<': 左移
- '>>': 右移
下面一一介紹
AND運算符'&' -- 按位與
按位與運算符"&"是雙目運算符少态。 其功能是將參與運算的兩數(shù)轉(zhuǎn)成32位二進制后, 各對應(yīng)的二進位相與。只有對應(yīng)的兩個二進位均為1時易遣,結(jié)果位才為1 彼妻,否則為0。
例如:
console.log(6&2); //輸出2
console.log(10&5); //輸出0
說明(下述文字中的二進制, 前面(28位)均為0, 所以省略了)
- 6的二進制位0110, 2的二進制位0010, 結(jié)果就是0010, 轉(zhuǎn)成十進制也就是2
- 10的二進制位為1010, 5的二進制位0101, 所以結(jié)果為0000, 也就是0
這個運算符, 我一般用它來獲取RGB顏色值中的藍色, 例如:
var rgbStr = "#6abc3a";
//將字符串轉(zhuǎn)成十進制整數(shù)
var rgb = parseInt(rgbStr.replace(/^\s*#|\s*$/g, ""), 16);
//獲取顏色值中的藍色
var b = rgb&0xff;
//輸出藍色值得16進制字符串
console.log(b.toString(16));//輸出: 3a
OR運算符'|' -- 按位或
按位或運算符“|”是雙目運算符。 其功能是將參與運算的兩數(shù)轉(zhuǎn)成32位二進制后, 各對應(yīng)的二進位相或侨歉。只要對應(yīng)的二個二進位有一個為1時屋摇,結(jié)果位就為1。
例如:
console.log(6 | 2); //輸出6
console.log(10 | 5); //輸出15
說明(下述文字中的二進制, 前面(28位)均為0, 所以省略了)
- 6的二進制位0110, 2的二進制位0010, 結(jié)果就是0110, 轉(zhuǎn)成十進制也就是6
- 10的二進制位為1010, 5的二進制位0101, 所以結(jié)果為1111, 也就是15
這個運算符可以用來對數(shù)值進行取證, 用起來應(yīng)該比Math.floor和Math.ceil方便, 實例如下
console.log(10.5 | 0);
console.log(10.3 | 0);
console.log(10.8 | 0);
以上的輸出結(jié)果都是10
注意: 無論正數(shù)還是負數(shù), 此方法只是刪除數(shù)字的小數(shù)部分, 所以
- 對正數(shù), 其運行的結(jié)果和Math.floor是一樣的;
- 對負數(shù), 其運行結(jié)果和Math.ceil是一樣的
下面是個例子
console.log(8.35 | 0); //輸出: 8
console.log(Math.floor(8.35)); //輸出: 8
console.log(Math.ceil(8.35)); //輸出: 9
console.log(-8.35 | 0); //輸出: -8
console.log(Math.floor(-8.35)); //輸出: -9
console.log(Math.ceil(-8.35)); //輸出: -8
取反運算符'~'
取反運算符為單目運算符幽邓,具有右結(jié)合性摊册。 其功能是對參與運算的數(shù)的各二進位按位取反
下面也舉一個例子
console.log(~2); //輸出-3
console.log(~5); //輸出-6
這里解說有點麻煩, 需要將所有的32位都列出來, 所以就不加說明了
注: 到目前為止, 我沒有在編程里面用到此運算符
異或運算符'^' -- 按位異或
按位異或運算符“^”是雙目運算符。 其功能是參與運算的兩數(shù)各對應(yīng)的二進位相異或颊艳,當兩對應(yīng)的二進位相異(即對應(yīng)位數(shù)值不相同, 也就是其中一個為1,另一個為0)時,結(jié)果為1忘分。
例如
console.log(6 ^ 2); //輸出4
console.log(10 ^ 5); //輸出15
說明(下述文字中的二進制, 前面(28位)均為0, 所以省略了)
- 6的二進制位0110, 2的二進制位0010, 結(jié)果就是0100, 轉(zhuǎn)成十進制也就是4
- 10的二進制位為1010, 5的二進制位0101, 所以結(jié)果為1111, 也就是15
此運算符可以用來交換兩個整型變量的值(不定義中間變量)
如
var a = 125, b = 10;
a = a ^ b;
b = a ^ b;
a = a ^ b;
console.log("a = "+ a + ", b = " + b);
//輸出: a = 10, b = 125
另外也可以判斷兩個整數(shù)是否相等, 如下
a ^ b == 0; //如果a,b相等, 為true, 否則為false
右移運算符'>>'
右移運算符“>>”是雙目運算符, 其功能是把“>>”左邊的運算數(shù)的各二進位全部右移若干位(不足位補0)棋枕,“>>”右邊的數(shù)指定移動的位數(shù)。
右移n位的結(jié)果相當于整除2的n次方后的值
例如
console.log(6>>2); //輸出: 1
console.log(10>>2); //輸出: 2
說明(下述文字中的二進制, 前面(28位)均為0, 所以省略了)
- 6的二進制位0110, 向右移兩位, 結(jié)果就是0001, 轉(zhuǎn)成十進制也就是1
- 10的二進制位為1010, 向右移兩位, 所以結(jié)果為0010, 也就是2
說明一下
m >> n, 相當于m / (2^n)[ 這里的^不是異或運算符, 而是2的n次方 ], 轉(zhuǎn)成js表達式就是Math.floor(m / Math.pow(2, n));
console.log(100>>4); //輸出: 6
console.log(Math.floor(100 / Math.pow(2,4))); //輸出: 6
console.log(120>>3); //輸出: 15
console.log(Math.floor(120 / Math.pow(2,3))); //輸出: 15
目前我主要用于RGB顏色值中R(紅色)的分離, 并配合按位與'&'運算符, 可以分離出G(綠色)
完整分離RGB顏色的代碼如下
var rgbStr = "#6abc3a";
//將字符串轉(zhuǎn)成十進制整數(shù)
var rgb = parseInt(rgbStr.replace(/^\s*#|\s*$/g, ""), 16);
//獲取顏色值中的藍色
var b = rgb&0xff;
var g = rgb>>8&0xff;
var r = rgb>>16;
//輸出RGB/R/G/G色值的16進制字符串
console.log("rgb = " + rgb.toString(16));//輸出: 6abc3a
console.log("r = " + r.toString(16));//輸出: 6a
console.log("g = " + g.toString(16));//輸出: bc
console.log("b = " + b.toString(16));//輸出: 3a
//下面可以分別對R/G/B值進行計算, 如下(將顏色值變亮)
r = Math.min(r*1.3, 255);
g = Math.min(g*1.3, 255);
b = Math.min(b*1.3, 255);
//最后在將各個分量組合(要用到左移運算符)在一起, 就可以應(yīng)用了
也可以用來對數(shù)值取整, 方法/結(jié)果和'|'是一樣的
左移運算符 '<<'
左移運算符“<<”是雙目運算符妒峦。左移n位就是乘以2的n次方重斑。 其功能把“<<”左邊的運算數(shù)的各二進位全部左移若干位,由“<<”右邊的數(shù)指定移動的位數(shù)肯骇,高位丟棄窥浪,低位補0
例如
console.log(6<<2); //相當于6*(2*2), 輸出: 24
console.log(10<<3); //相當于10*(2*2*2), 輸出: 80
我常用于顏色分量的合成, 接著上述右移運算符的顏色例子
var newRGB = (r<<16)+(r<<8)+(g)
//或者可以用按位或 '|'
//var newRGB = (r<<16)|(r<<8)|(g)
下面是一個顏色值的完整例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
.container{ width: 250px;text-align: center; margin: 0 auto;}
#rect{ width: 120px; height: 65px; background-color: #68a28b; margin: 10px auto;}
button{margin-right: 20px;}
</style>
</head>
<body>
<div class="container">
<div id="rect"></div>
<button id="light">加亮</button>
<button id="reset">重置</button>
<button id="dark">變暗</button>
</div>
<script>
var rect = document.getElementById("rect");
var light = document.getElementById("light");
var reset = document.getElementById("reset");
var dark = document.getElementById("dark");
var initColor = "#68a28b";
var newColor = initColor;
light.addEventListener("click", function (){
ld(1.1, Math.min, 255);
});
dark.addEventListener("click", function (){
ld(0.9, Math.max, 0);
});
reset.addEventListener("click", function (){
newColor = initColor;
rect.style.backgroundColor = newColor;
});
function ld(factor, func, mom){
var obj = fl(newColor);
console.log(obj);
obj.r = func(obj.r*factor, mom)|0;
obj.g = func(obj.g*factor,mom)|0;
obj.b = func(obj.b*factor, mom)|0;
console.log(obj);
newColor = "#" + hc(obj).toString(16);
rect.style.backgroundColor = newColor;
}
//分離R/G/B
function fl(rgb){
if(rgb.constructor == String)
rgb = parseInt(rgb.replace(/^\s*#|\s*$/g, ""), 16);
var obj = {};
obj.r = rgb>>16;
obj.g = rgb>>8&0xff;
obj.b = rgb&0xff;
return obj;
}
//合并RGB
function hc(obj){
return (obj.r<<16)|(obj.g<<8)|(obj.b);
}
</script>
</body>
</html>