JS中的位運算

前端小白ML發表於2019-12-26

JS中的位運算

  • 所有 JavaScript 數字儲存為根為 10 的 64(8位元)浮點數。JavaScript 不是型別語言。與許多其他程式語言不同,JavaScript 不定義不同型別的數字,比如整數、短、長、浮點等等。
  • 整數精度(不使用小數點或指數計數法)最多為 15 位。小數精度的最大位數是17,但是浮點運算並不總是 100% 準確。
  • 位運算直接對二進位制位進行計算,位運算直接處理每一個位元位,是非常底層的運算,好處是速度極快,缺點是很不直觀,許多場合不能夠使用。
  • 位運算只對整數起作用,如果一個運算數不是整數,會自動轉為整數後再執行。 在 JavaScript 內部,數值都是以 64 位浮點數的形式儲存,但是做位運算的時候,是以 32 位帶符號的整數進行運算的,並且返回值也是一個32 位帶符號的整數。

位運算子用於直接對二進位制位進行計算,一共有7個。

  • 二進位制或運算子(or):符號為|,表示若兩個二進位制位都為0,則結果為0,否則為1。
  • 二進位制與運算子(and):符號為&,表示若兩個二進位制位都為1,則結果為1,否則為0。
  • 二進位制否運算子(not):符號為~,表示對一個二進位制位取反。
  • 異或運算子(xor):符號為^,表示若兩個二進位制位不相同,則結果為1,否則為0。
  • 左移運算子(left shift):符號為<<
  • 右移運算子(right shift):符號為>>
  • 帶符號位的右移運算子(zero filled right shift):符號為>>>

JS 中的 7 個位元素符。

1. 按位與(and) &

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

// 1的二進位制表示為: 00000000 00000000 00000000 00000001
// 3的二進位制表示為: 00000000 00000000 00000000 00000011
// -----------------------------
// 1的二進位制表示為: 00000000 00000000 00000000 00000001
console.log(1 & 3)     // 1
複製程式碼

2.按位或(OR) |

| 運算子跟 & 的區別在於如果對應的位中任一個運算元為 1 那麼結果就是 1。

// 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。

// 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.有符號右移 >>

>> 該操作符會將指定運算元的二進位制位向右移動指定的位數。向右被移出的位被丟棄,拷貝最左側的位以填充左側。由於新的最左側的位總是和以前相同,符號位沒有被改變。所以被稱作“符號傳播”。

// 1的二進位制表示為: 00000000 00000000 00000000 00000001
// -----------------------------
// 0的二進位制表示為: 00000000 00000000 00000000 00000000
console.log(1 >> 1)     // 0
複製程式碼

7.無符號右移 >>>

>>> 該操作符會將第一個運算元向右移動指定的位數。向右被移出的位被丟棄,左側用0填充。因為符號位變成了 0,所以結果總是非負的。(譯註:即便右移 0 個位元,結果也是非負的。)

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

相關文章