JavaScript中7種位運算符在實戰(zhàn)的妙用
本篇文章帶大家了解一下JavaScript中的7種位運算符,看看如何妙用這7種位運算符,希望對大家有所幫助!
位運算符
ECMAScript 中的所有數(shù)值都以 IEEE 754 64 位格式存儲,但位操作并不直接應(yīng)用到 64 位表示,而是先把值轉(zhuǎn)換為 32 位整數(shù),再進(jìn)行位操作,之后再把結(jié)果轉(zhuǎn)換為 64 位。
對開發(fā)者而言,就好像只有 32 位整數(shù)一樣,因 為 64 位整數(shù)存儲格式是不可見的。既然知道了這些,就只需要考慮 32 位整數(shù)即可。
有符號整數(shù)使用 32 位的前 31 位表示整數(shù)值。第 32 位表示數(shù)值的符號,如 0 表示正,1 表示負(fù)。這 一位稱為符號位(sign bit),它的值決定了數(shù)值其余部分的格式。正值以真正的二進(jìn)制格式存儲,即 31 位中的每一位都代表 2 的冪。第一位(稱為第 0 位)表示 20 ,第二位表示 21 ,依此類推。
如果一個位是空的,則以0填充,相當(dāng)于忽略不計。比如,數(shù)值18的二進(jìn)制格式為00000000000000000000000000010010, 或更精簡的 10010。后者是用到的 5 個有效位,決定了實際的值(如下圖所示)。
按位非 ~
按位非操作符用波浪符(~)表示,它的作用是返回數(shù)值的一補(bǔ)數(shù)。按位非是 ECMAScript 中為數(shù) 不多的幾個二進(jìn)制數(shù)學(xué)操作符之一。看下面的例子:
let num1 = 25; //二進(jìn)制 00000000000000000000000000011001 let num2 = ~num1; // 二進(jìn)制 11111111111111111111111111100110 console.log(num2); // -26
這里,按位非操作符作用到了數(shù)值 25,得到的結(jié)果是?26。由此可以看出,按位非的最終效果是對 數(shù)值取反并減 1,就像執(zhí)行如下操作的結(jié)果一樣:
let num1 = 25; let num2 = -num1 - 1; console.log(num2); // "-26"
實際上,盡管兩者返回的結(jié)果一樣,但位操作的速度快得多。這是因為位操作是在數(shù)值的底層表示 上完成的。
按位與 &
按位與操作符用和號(&)表示,有兩個操作數(shù)。本質(zhì)上,按位與就是將兩個數(shù)的每一個位對齊, 然后基于真值表中的規(guī)則,對每一位執(zhí)行相應(yīng)的與操作。
按位與操作在兩個位都是 1 時返回 1,在任何一位是 0 時返回 0。 下面看一個例子,我們對數(shù)值 25 和 3 求與操作,如下所示:
let result = 25 & 3; console.log(result); // 1 25 和 3 的按位與操作的結(jié)果是 1。
為什么呢?看下面的二進(jìn)制計算過程:
如上圖所示,25 和 3 的二進(jìn)制表示中,只有第 0 位上的兩個數(shù)都是 1。于是結(jié)果數(shù)值的所有其他位都 會以 0 填充,因此結(jié)果就是 1。
按位或 |
按位或操作符用管道符(|)表示,同樣有兩個操作數(shù)。按位或遵循如下真值表:
按位或操作在至少一位是 1 時返回 1,兩位都是 0 時返回 0。 仍然用按位與的示例,如果對 25 和 3 執(zhí)行按位或,代碼如下所示:
let result = 25 | 3; console.log(result); // 27
可見 25 和 3 的按位或操作的結(jié)果是 27:
在參與計算的兩個數(shù)中,有 4 位都是 1,因此它們直接對應(yīng)到結(jié)果上。二進(jìn)制碼 11011 等于 27。
按位異或 ^
按位異或用脫字符(^)表示,同樣有兩個操作數(shù)。下面是按位異或的真值表:
按位異或與按位或的區(qū)別是,它只在一位上是 1 的時候返回 1(兩位都是 1 或 0,則返回 0)。 對數(shù)值 25 和 3 執(zhí)行按位異或操作:
let result = 25 ^ 3; console.log(result); // 26
可見,25 和 3 的按位異或操作結(jié)果為 26,如下所示:
兩個數(shù)在 4 位上都是 1,但兩個數(shù)的第 0 位都是 1,因此那一位在結(jié)果中就變成了 0。其余位上的 1 在另一個數(shù)上沒有對應(yīng)的 1,因此會直接傳遞到結(jié)果中。二進(jìn)制碼 11010 等于 26。(注意,這比對同樣 兩個值執(zhí)行按位或操作得到的結(jié)果小 1。)
左移 <<
左移操作符用兩個小于號(<<)表示,會按照指定的位數(shù)將數(shù)值的所有位向左移動。比如,如果數(shù) 值 2(二進(jìn)制 10)向左移 5 位,就會得到 64(二進(jìn)制 1000000),如下所示:
let oldValue = 2; // 等于二進(jìn)制 10 let newValue = oldValue << 5; // 等于二進(jìn)制 1000000,即十進(jìn)制 64
注意在移位后,數(shù)值右端會空出 5 位。左移會以 0 填充這些空位,讓結(jié)果是完整的 32 位數(shù)值(見下圖)。
注意,左移會保留它所操作數(shù)值的符號。比如,如果-2 左移 5 位,將得到-64,而不是正 64。
有符號右移 >>
有符號右移由兩個大于號(>>)表示,會將數(shù)值的所有 32 位都向右移,同時保留符號(正或負(fù))。 有符號右移實際上是左移的逆運算。比如,如果將 64 右移 5 位,那就是 2:
let oldValue = 64; // 等于二進(jìn)制 1000000 let newValue = oldValue >> 5; // 等于二進(jìn)制 10,即十進(jìn)制 2
同樣,移位后就會出現(xiàn)空位。不過,右移后空位會出現(xiàn)在左側(cè),且在符號位之后(見圖 3-3)。 ECMAScript 會用符號位的值來填充這些空位,以得到完整的數(shù)值。
無符號右移 >>>
無符號右移用 3 個大于號表示(>>>),會將數(shù)值的所有 32 位都向右移。對于正數(shù),無符號右移與 有符號右移結(jié)果相同。仍然以前面有符號右移的例子為例,64 向右移動 5 位,會變成 2:
let oldValue = 64; // 等于二進(jìn)制 1000000 let newValue = oldValue >>> 5; // 等于二進(jìn)制 10,即十進(jìn)制 2
對于負(fù)數(shù),有時候差異會非常大。與有符號右移不同,無符號右移會給空位補(bǔ) 0,而不管符號位是 什么。對正數(shù)來說,這跟有符號右移效果相同。但對負(fù)數(shù)來說,結(jié)果就差太多了。無符號右移操作符將負(fù)數(shù)的二進(jìn)制表示當(dāng)成正數(shù)的二進(jìn)制表示來處理。因為負(fù)數(shù)是其絕對值的二補(bǔ)數(shù),所以右移之后結(jié)果變 得非常之大,如下面的例子所示:
let oldValue = -64; // 等于二進(jìn)制 11111111111111111111111111000000 let newValue = oldValue >>> 5; // 等于十進(jìn)制 134217726
在對-64 無符號右移 5 位后,結(jié)果是 134 217 726。這是因為-64 的二進(jìn)制表示是 1111111111111111111 1111111000000,無符號右移卻將它當(dāng)成正值,也就是 4 294 967 232。把這個值右移 5 位后,結(jié)果是 00000111111111111111111111111110,即 134 217 726。
實戰(zhàn)中的妙用
1.判斷奇偶數(shù)
// 偶數(shù) & 1 = 0 // 奇數(shù) & 1 = 1 console.log(2 & 1) // 0 console.log(3 & 1) // 1
2. 使用^來完成值的交換
let a = 2 let b = 5 a ^= b b ^= a a ^= b console.log(a) // 5 console.log(b) // 2
3. 使用~進(jìn)行判斷
// 常用判斷 if (arr.indexOf(item) > -1) { // code } // 按位非 ~-1 = -(-1) - 1 取反再 -1 if (~arr.indexOf(item)) { // code }
4. 使用&、>>、|來完成rgb值和16進(jìn)制顏色值之間的轉(zhuǎn)換
/** * 16進(jìn)制顏色值轉(zhuǎn)RGB * @param {String} hex 16進(jìn)制顏色字符串 * @return {String} RGB顏色字符串 */ function hexToRGB(hex) { var hexx = hex.replace('Id', '0x') var r = hexx >> 16 var g = hexx >> 8 & 0xff var b = hexx & 0xff return `rgb(${r}, ${g}, $)` } /** * RGB顏色轉(zhuǎn)16進(jìn)制顏色 * @param {String} rgb RGB進(jìn)制顏色字符串 * @return {String} 16進(jìn)制顏色字符串 */ function RGBToHex(rgb) { var rgbArr = rgb.split(/[^\d]+/) var color = rgbArr[1]<<16 | rgbArr[2]<<8 | rgbArr[3] return 'Id'+ color.toString(16) } // ------------------------------------------------- hexToRGB('Idffffff') // 'rgb(255,255,255)' RGBToHex('rgb(255,255,255)') // 'Idffffff'
5. 使用|、~、>>、<<、>>>來取整
console.log(~~ 3.1415) // 3 console.log(3.1415 >> 0) // 3 console.log(3.1415 << 0) // 3 console.log(3.1415 | 0) // 3 // >>>不可對負(fù)數(shù)取整 console.log(3.1415 >>> 0) // 3
【相關(guān)推薦:】
以上就是聊聊JavaScript中的7種位運算符,看看在實戰(zhàn)中如何妙用?的詳細(xì)內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!
參考地址:http://www.php.cn//js-tutorial-487096.html
到此這篇關(guān)于JavaScript中7種位運算符在實戰(zhàn)的妙用的文章就介紹到這了,更多相關(guān)JS位運算符實戰(zhàn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Three.js中的紋理圖像應(yīng)用和屬性調(diào)整方法
在three.js中紋理貼圖是用來給物體表面添加圖案、顏色或者其他視覺效果的一種技術(shù),這篇文章主要給大家介紹了關(guān)于Three.js中紋理圖像應(yīng)用和屬性調(diào)整的相關(guān)資料,需要的朋友可以參考下2024-01-01詳解Javascript數(shù)據(jù)類型的轉(zhuǎn)換規(guī)則
本文主要介紹了Javascript的基本數(shù)據(jù)類型和數(shù)據(jù)類型的轉(zhuǎn)換規(guī)則。具有很好的參考價值,需要的朋友可以看下2016-12-12