位運算符在JS中的妙用

  • 全部 JavaScript 數字存儲爲根爲10的64(8比特)浮點數。JavaScript不是類型語言。與許多其餘編程語言不一樣,JavaScript不定義不一樣類型的數字,好比整數、短、長、浮點等等。
  • 整數精度(不使用小數點或指數計數法)最多爲15位。小數精度的最大位數是17,可是浮點運算並不老是100% 準確。
  • 位運算直接對二進制位進行計算,位運算直接處理每個比特位,是很是底層的運算,好處是速度極快,缺點是很不直觀,許多場合不可以使用。
  • 位運算只對整數起做用,若是一個運算數不是整數,會自動轉爲整數後再運行。
  • JavaScript內部,數值都是以64位浮點數的形式儲存,可是作位運算的時候,是以32位帶符號的整數進行運算的,而且返回值也是一個32位帶符號的整數。

JS中經常使用的7個位運算符

1. 按位與(AND) &

&以特定的方式組合操做二進制數中對應的位,若是對應的位都爲1,那麼結果就是1, 若是任意一個位是0 則結果就是0。javascript

// 1的二進制表示爲: 00000000 00000000 00000000 00000001
// 3的二進制表示爲: 00000000 00000000 00000000 00000011
// -----------------------------
// 1的二進制表示爲: 00000000 00000000 00000000 00000001
console.log(1 & 3)     // 1
複製代碼

2. 按位或(OR) |

| 運算符跟 & 的區別在於若是對應的位中任一個操做數爲1 那麼結果就是1。html

// 1的二進制表示爲: 00000000 00000000 00000000 00000001
// 3的二進制表示爲: 00000000 00000000 00000000 00000011
// -----------------------------
// 3的二進制表示爲: 00000000 00000000 00000000 00000011
console.log(1 | 3)     // 3
複製代碼

3. 按位異或(XOR) ^

^ 若是對應兩個操做位有且僅有一個1時結果爲1,其餘都是0。java

// 1的二進制表示爲: 00000000 00000000 00000000 00000001
// 3的二進制表示爲: 00000000 00000000 00000000 00000011
// -----------------------------
// 2的二進制表示爲: 00000000 00000000 00000000 00000010
console.log(1 ^ 3)     // 2
複製代碼

4. 按位非(NOT) ~

~ 運算符是對位求反,1變0, 0變1,也就是求二進制的反碼。編程

// 1的二進制表示爲: 00000000 00000000 00000000 00000001
// 3的二進制表示爲: 00000000 00000000 00000000 00000011
// -----------------------------
// 1反碼二進制表示: 11111111 11111111 11111111 11111110
// 因爲第一位(符號位)是1,因此這個數是一個負數。JavaScript 內部採用補碼形式表示負數,即須要將這個數減去1,再取一次反,而後加上負號,才能獲得這個負數對應的10進制值。
// -----------------------------
// 1的反碼減1: 11111111 11111111 11111111 11111101
// 反碼取反: 00000000 00000000 00000000 00000010
// 表示爲10進制加負號:-2
console.log(~ 1)     // -2
複製代碼
  • 簡單記憶:一個數與自身的取反值相加等於-1

5. 左移(Left shift)<<

<<運算符使指定值的二進制數全部位都左移指定次數,其移動規則:丟棄高位,低位補0即按二進制形式把全部的數字向左移動對應的位數,高位移出(捨棄),低位的空位補零。編程語言

// 1的二進制表示爲: 00000000 00000000 00000000 00000001
// -----------------------------
// 2的二進制表示爲: 00000000 00000000 00000000 00000010
console.log(1 << 1)     // 2
複製代碼

6. 有符號右移>>

>>該操做符會將指定操做數的二進制位向右移動指定的位數。向右被移出的位被丟棄,拷貝最左側的位以填充左側。因爲新的最左側的位老是和之前相同,符號位沒有被改變。因此被稱做「符號傳播」。ui

// 1的二進制表示爲: 00000000 00000000 00000000 00000001
// -----------------------------
// 0的二進制表示爲: 00000000 00000000 00000000 00000000
console.log(1 >> 1)     // 0
複製代碼

7. 無符號右移>>>

>>>該操做符會將第一個操做數向右移動指定的位數。向右被移出的位被丟棄,左側用0填充。由於符號位變成了 0,因此結果老是非負的。(譯註:即使右移 0 個比特,結果也是非負的。)spa

對於非負數,有符號右移和無符號右移老是返回相同的結果。例如, 9 >>> 2 獲得 2 和 9 >> 2 相同。code

位運算符在js中的妙用

  1. 使用&運算符判斷一個數的奇偶
// 偶數 & 1 = 0
// 奇數 & 1 = 1
console.log(2 & 1)    // 0
console.log(3 & 1)    // 1
複製代碼
  1. 使用~, >>, <<, >>>, |來取整
console.log(~~ 6.83)    // 6
console.log(6.83 >> 0)  // 6
console.log(6.83 << 0)  // 6
console.log(6.83 | 0)   // 6
// >>>不可對負數取整
console.log(6.83 >>> 0)   // 6
複製代碼
  1. 使用^來完成值交換
var a = 5
var b = 8
a ^= b
b ^= a
a ^= b
console.log(a)   // 8
console.log(b)   // 5
複製代碼
  1. 使用&, >>, |來完成rgb值和16進制顏色值之間的轉換
/** * 16進制顏色值轉RGB * @param {String} hex 16進制顏色字符串 * @return {String} RGB顏色字符串 */
  function hexToRGB(hex) {
    var hexx = hex.replace('#', '0x')
    var r = hexx >> 16
    var g = hexx >> 8 & 0xff
    var b = hexx & 0xff
    return `rgb(${r}, ${g}, ${b})`
}

/** * RGB顏色轉16進制顏色 * @param {String} rgb RGB進制顏色字符串 * @return {String} 16進制顏色字符串 */
function RGBToHex(rgb) {
    var rgbArr = rgb.split(/[^\d]+/)
    var color = rgbArr[1]<<16 | rgbArr[2]<<8 | rgbArr[3]
    return '#'+ color.toString(16)
}
// -------------------------------------------------
hexToRGB('#ffffff')               // 'rgb(255,255,255)'
RGBToHex('rgb(255,255,255)')      // '#ffffff'
複製代碼

參考

  1. https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
  2. http://javascript.ruanyifeng.com/grammar/operator.html
  3. http://www.w3school.com.cn/js/js_obj_number.asp
相關文章
相關標籤/搜索