iT邦幫忙

DAY 3
8

Javascript系列 第 3

Javascript中的位元運算子 (2)

討論邏輯運算子(logical operators)與位元運算子(bitwise operators)的使用情境

Part I. logical operators
Part II. bitwise operators (1)
Part II. bitwise operators (2)
Part II. bitwise operators (3)
實例 1: RGB的操作

我們在進行網站開發時,有時候會需要操作到色碼,例如想從 0xEEB422 中分別抓出 RGB,這要怎麼做呢?

最基本的做法可以用substr,但看起來就不太漂亮... (雖然漂亮也不能當飯吃啦)

如果不想用字串的方式去處理,那可以考慮一下利用位元運算子去轉換,首先,我們先把色碼轉換成2位元看一下:
0xEEB422 = 1110 1110 1011 0100 0010 0010
我們要抓的 RGB 其中的 R 其實就是這組位元組中的前 8 位、G 就是中間 8 位、B就是最後的 8 位。
R = 1110 1110
G = 1011 0100
B = 0010 0010
問題是應該要怎麼抓出來呢?
首先看 R,R既然是前 8 位,那就把後面的 16 位擠掉就好了,也就是:

var color = 0xEEB422;
var r = color >> 16;

把 color 右移 16 位,不就是把右邊的 16 位給擠掉嗎?這樣就可以很輕鬆地拿到了 R。

G 是中間 8 位,那我們先把右邊的 8 位給擠掉:

var color = 0xEEB422;
var g = color >> 8;
console.log(g, g.toString(2));  // 61108 '1110111010110100'

根據我們印出來的結果,是把右邊 8 位給擠掉了,但是左邊的 R 也還在,如果想把左邊的 8 位的 R 拿掉就還需要另外處理一下:

g = g & 0xff; 	         // 0xff = 255 --> 0000000011111111
console.log(g, g.toString(2));  // 180 '10110100'

我們用人工的方式看一下:

這邊利用了 & 的特性,& 是當兩者都是 1 的時候才會回傳 1,因為我們不想要最前面的 8 位,所以讓前面的 8 位是 0,這樣 & 出來的結果就會不見。而右邊的 8 位想要保留,因為右邊的 8 位都是 1,這樣就能保留原本右邊的 8 位。

接下來,就是最右邊的 B 了,我當時的第一個直覺反應是,能不能跟 R 一樣,很簡單的擠掉左邊的 16 位就好,結果就是:

var b = color << 16;
console.log(b, b.toString(2));   
// -1272840192 '-1001011110111100000000000000000'

結果真的是非常得慘不忍睹,看來是不能採用取 R 的那招了,那取 G 的招數呢?仔細思考一下,B是要保留右邊的 8 位,也就是把前面的 16 位變成 0,於是:

var b = color & 0xff;
console.log(b, b.toString(2));  // 34 '00100010'

果然,利用跟 0 & 會變 0,跟 1 & 會變自己的特性,成功的取得了 B。

完整的函式如下:

function getRGB(color) {
	var rgb = {};
	rgb.r = color >> 16;
	rgb.g = (color >> 8) & 0xff;
	rgb.b = color & 0xff;
	return rgb;
}

上一篇
Javascript中的位元運算子 (1)
下一篇
javascript中的位元運算子 (3)
系列文
Javascript7

1 則留言

我要留言

立即登入留言