From 43a5cac2eff22c21071800e13bef12af9d3a37d0 Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 13:12:08 +0100 Subject: unslug zh-tw: move --- .../operators/bitwise_operators/index.html | 555 --------------------- 1 file changed, 555 deletions(-) delete mode 100644 files/zh-tw/web/javascript/reference/operators/bitwise_operators/index.html (limited to 'files/zh-tw/web/javascript/reference/operators/bitwise_operators') diff --git a/files/zh-tw/web/javascript/reference/operators/bitwise_operators/index.html b/files/zh-tw/web/javascript/reference/operators/bitwise_operators/index.html deleted file mode 100644 index 86f78270b5..0000000000 --- a/files/zh-tw/web/javascript/reference/operators/bitwise_operators/index.html +++ /dev/null @@ -1,555 +0,0 @@ ---- -title: 位元運算子 -slug: Web/JavaScript/Reference/Operators/Bitwise_Operators -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Bitwise_Operators ---- -
{{jsSidebar("Operators")}}
- -

位元運算子將運算元視為一段 32 位元長的 0 和 1 序列,而不是十進位、十六進位或八進位的 Numbers。 舉例來說,十進位的 9 可以用二進位表示為 1001。位元運算子對這樣的二進位表示法進行運算,然後回傳標準 JavaScript 數值。

- -
{{EmbedInteractiveExample("pages/js/expressions-bitwiseoperators.html")}}
- - - -

下表總結了 JavaScript 的位元運算子:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperatorUsageDescription
位元 ANDa & b當兩運算元的該位置皆為 1 時,回傳值的該位置為 1
位元 ORa | b當兩運算元的該位置有一者為 1 時,回傳值的該位置為 1
位元 XORa ^ b當兩運算元的該位置恰好一者為 1 時,回傳值的該位置為 1
位元 NOT~ a將運算元的所有位元反轉。
左移a << b將 a 的二進位表示法左移 b (< 32) 位元,右側補 0
保持符號右移a >> b將 a 的二進位表示法右移 b (< 32) 位元,拋棄被移出的位元。
填零右移a >>> b  將 a 的二進位表示法右移 b (< 32) 位元,拋棄被移出的位元,並於右側補 0
- -

帶號的 32位元整數

- -

所有位元運算子的運算元皆會被轉換成二補數系統下的帶號32位元整數。二補數系統意味著一個整數的加法反元素(例如 5和 -5)是該整數的所有位元反轉(位元 NOT,也就是該數的一補數) 再加一。舉例來說,下面的序列代表著整數 314:

- -
00000000000000000000000100111010
-
- -

下面的序列代表 ~314,也就是 314 的一補數:

- -
11111111111111111111111011000101
-
- -

接著,下面代表著 -314,也就是 314 的二補數:

- -
11111111111111111111111011000110
-
- -

二補數系統確保了正值時最左邊的位元為 0,反之則為 1。因此,最左邊的位元被稱作符號位。

- -

整數 0 全由位元 0組成。

- -
0 (base 10) = 00000000000000000000000000000000 (base 2)
-
- -

整數 -1 全由位元 1組成。

- -
-1 (base 10) = 11111111111111111111111111111111 (base 2)
-
- -

整數 -2147483648 (十六進位: -0x80000000) 除了第一位為 1,其餘皆由位元 0組成。

- -
-2147483648 (base 10) = 10000000000000000000000000000000 (base 2)
-
- -

整數 -2147483648 (十六進位: -0x7fffffff) 除了第一位為 0,其餘皆由位元 1組成。

- -
2147483647 (base 10) = 01111111111111111111111111111111 (base 2)
-
- -

整數 -2147483648 和 2147483647 分別為帶號32位元整數所能表示的最小值和最大值。

- -

位元邏輯運算子

- -

大致上,位元邏輯運算子的運作如下︰

- - - -

& (位元 AND)

- -

對每一組位元執行 AND 運算。a AND b 只在 a 和 b 同時為 1 時得到 1。AND運算的真值表如下:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
aba AND b
000
010
100
111
- -
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
-    14 (base 10) = 00000000000000000000000000001110 (base 2)
-                   --------------------------------
-14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
-
- -

將任何數 x 和 0 做位元 AND 皆會得到 0。將任何數 x 和 -1 做位元 AND 皆會得到 x

- -

| (位元 OR)

- -

對每一組位元執行 OR 運算。a OR b 在 a 和 b 有一者為 1 時得到 1。OR運算的真值表如下:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
aba OR b
000
011
101
111
- -
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
-    14 (base 10) = 00000000000000000000000000001110 (base 2)
-                   --------------------------------
-14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
-
- -

將任何數 x 和 0 做位元 OR 皆會得到 x。將任何數 x 和 -1 做位元 OR 皆會得到 -1

- -

^ (位元 XOR)

- -

對每一組位元執行 XOR 運算。a XOR b 只在 a 和 b 恰一者為 1 時得到 1。XOR運算的真值表如下:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
aba XOR b
000
011
101
110
- -
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
-    14 (base 10) = 00000000000000000000000000001110 (base 2)
-                   --------------------------------
-14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
-
- -

將任何數 x 和 0 做位元 AND 皆會得到 x。將任何數 x 和 -1 做位元 AND 皆會得到 ~x

- -

~ (位元 NOT)

- -

對每一個位元執行 NOT 運算。NOT a 會得到 a 的反轉值(也就是一補數)。NOT運算的真值表如下:

- - - - - - - - - - - - - - - - -
aNOT a
01
10
- -
 9 (base 10) = 00000000000000000000000000001001 (base 2)
-               --------------------------------
-~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
-
- -

將任何數 x 做位元 NOT 皆會得到 -(x + 1)。舉例來說,~-5 會得到 4

- -

值得注意的是,因為使用 32位元表示法表示數值 ~-1 和 ~4294967295 (232-1) 皆會得到 0

- -

位元位移運算子

- -

位移運算子需要兩個運算元:第一個是要被位移的值,第二個是位元位移量。位移的方向取決於使用的運算子。

- -

位移運算子將運算元轉換成 32位元的大端序整數並回傳一個與左運算元相同類別的值。右運算元應不大於32,如果超過的話,將只會使用後 5個位元。

- -

<< (左移)

- -

將第一個運算元向左位移指定的量。被移出的位元會被拋棄,並從右側補零。

- -

例如,9 << 2 會得到 36:

- -
.    9 (base 10): 00000000000000000000000000001001 (base 2)
-                  --------------------------------
-9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
-
- -

將任意值 x 左移 y 位元會得到 x * 2 ** y

- -

>> (保持符號右移)

- -

將第一個運算元向右位移指定的量。被移出的位元會被拋棄,並從左側補進和原本最左端相同的位元值。因為新的最左端位元和原本的最左端位元是一樣的,符號位(最左端位元)並不會改變。「保持符號」之名便是因此。

- -

例如,9 >> 2 會得到 2:

- -
.    9 (base 10): 00000000000000000000000000001001 (base 2)
-                  --------------------------------
-9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
-
- -

同樣地,-9 >> 2 會得到 -3,因為符號會保持不變。

- -
.    -9 (base 10): 11111111111111111111111111110111 (base 2)
-                   --------------------------------
--9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
-
- -

>>> (填零右移)

- -

將第一個運算元向右位移指定的量。被移出的位元會被拋棄,並從左側補零。因為符號位變成 0,所以結果永遠都是正值。

- -

對非負的數來說,填零右移會得到和保持符號右移一樣的結果。例如,9 >>> 2 和 9 >> 2 一樣,皆會得到 2:

- -
.     9 (base 10): 00000000000000000000000000001001 (base 2)
-                   --------------------------------
-9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
-
- -

然而對負值來說並不是這麼一回事。例如,-9 >>> 2 會得到 1073741821,跟 -9 >> 2 (得到 -3)的結果是不一樣的:

- -
.     -9 (base 10): 11111111111111111111111111110111 (base 2)
-                    --------------------------------
--9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
-
- -

範例

- -

旗標(flags) 和遮罩 (bitmasks)

- -

位元運算子常被用於生成、修改、和讀取旗標序列,就像是二進制的變數一般。雖然也可以使用普通變數,但使用二進制的旗標序列大大的減少了所需空間 (32 倍)。

- -

假設有 4個旗標:

- - - -

這些旗標倍表達成一個位元序列:DCBA。當一個旗標被立起 (set)時,其值為1。當一個旗標被放下 (clear),其值為0。假設有一變數 flags 的二進位值為 0101:

- -
var flags = 5;   // 二進位 0101
-
- -

這個值表示:

- - - -

因為位元運算子進行的是 32位元操作,0101 實際上是 00000000000000000000000000000101,但前導的 0可被忽略因為他們沒有實際上的意義。

- -

位元遮罩則為一個可以修改且(或)讀取旗標序列的位元序列。通常為每個單獨旗標為真的「初始」值:

- -
var FLAG_A = 1; // 0001
-var FLAG_B = 2; // 0010
-var FLAG_C = 4; // 0100
-var FLAG_D = 8; // 1000
-
- -

新的位元遮罩可以透過對初始遮罩進行位元運算獲得。例如,遮罩 1011 可以透過對 FLAG_A、FLAG_B、和 FLAG_D進行 OR運算獲得:

- -
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
-
- -

Individual flag values can be extracted by ANDing them with a bitmask, where each bit with the value of one will "extract" the corresponding flag. The bitmask masks out the non-relevant flags by ANDing with zeroes (hence the term "bitmask"). For example, the bitmask 0100 can be used to see if flag C is set:

- -
// if we own a cat
-if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
-   // do stuff
-}
-
- -

A bitmask with multiple set flags acts like an "either/or". For example, the following two are equivalent:

- -
// if we own a bat or we own a cat
-// (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true
-if ((flags & FLAG_B) || (flags & FLAG_C)) {
-   // do stuff
-}
-
- -
// if we own a bat or cat
-var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110
-if (flags & mask) { // 0101 & 0110 => 0100 => true
-   // do stuff
-}
-
- -

Flags can be set by ORing them with a bitmask, where each bit with the value one will set the corresponding flag, if that flag isn't already set. For example, the bitmask 1100 can be used to set flags C and D:

- -
// yes, we own a cat and a duck
-var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
-flags |= mask;   // 0101 | 1100 => 1101
-
- -

Flags can be cleared by ANDing them with a bitmask, where each bit with the value zero will clear the corresponding flag, if it isn't already cleared. This bitmask can be created by NOTing primitive bitmasks. For example, the bitmask 1010 can be used to clear flags A and C:

- -
// no, we don't have an ant problem or own a cat
-var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010
-flags &= mask;   // 1101 & 1010 => 1000
-
- -

The mask could also have been created with ~FLAG_A & ~FLAG_C (De Morgan's law):

- -
// no, we don't have an ant problem, and we don't own a cat
-var mask = ~FLAG_A & ~FLAG_C;
-flags &= mask;   // 1101 & 1010 => 1000
-
- -

Flags can be toggled by XORing them with a bitmask, where each bit with the value one will toggle the corresponding flag. For example, the bitmask 0110 can be used to toggle flags B and C:

- -
// if we didn't have a bat, we have one now,
-// and if we did have one, bye-bye bat
-// same thing for cats
-var mask = FLAG_B | FLAG_C;
-flags = flags ^ mask;   // 1100 ^ 0110 => 1010
-
- -

Finally, the flags can all be flipped with the NOT operator:

- -
// entering parallel universe...
-flags = ~flags;    // ~1010 => 0101
-
- -

Conversion snippets

- -

Convert a binary String to a decimal Number:

- -
var sBinString = '1011';
-var nMyNumber = parseInt(sBinString, 2);
-alert(nMyNumber); // prints 11, i.e. 1011
-
- -

Convert a decimal Number to a binary String:

- -
var nMyNumber = 11;
-var sBinString = nMyNumber.toString(2);
-alert(sBinString); // prints 1011, i.e. 11
-
- -

Automate Mask Creation

- -

You can create multiple masks from a set of Boolean values, like this:

- -
function createMask() {
-  var nMask = 0, nFlag = 0, nLen = arguments.length > 32 ? 32 : arguments.length;
-  for (nFlag; nFlag < nLen; nMask |= arguments[nFlag] << nFlag++);
-  return nMask;
-}
-var mask1 = createMask(true, true, false, true); // 11, i.e.: 1011
-var mask2 = createMask(false, false, true); // 4, i.e.: 0100
-var mask3 = createMask(true); // 1, i.e.: 0001
-// etc.
-
-alert(mask1); // prints 11, i.e.: 1011
-
- -

Reverse algorithm: an array of booleans from a mask

- -

If you want to create an Array of Booleans from a mask you can use this code:

- -
function arrayFromMask(nMask) {
-  // nMask must be between -2147483648 and 2147483647
-  if (nMask > 0x7fffffff || nMask < -0x80000000) {
-    throw new TypeError('arrayFromMask - out of range');
-  }
-  for (var nShifted = nMask, aFromMask = []; nShifted;
-       aFromMask.push(Boolean(nShifted & 1)), nShifted >>>= 1);
-  return aFromMask;
-}
-
-var array1 = arrayFromMask(11);
-var array2 = arrayFromMask(4);
-var array3 = arrayFromMask(1);
-
-alert('[' + array1.join(', ') + ']');
-// prints "[true, true, false, true]", i.e.: 11, i.e.: 1011
-
- -

You can test both algorithms at the same time…

- -
var nTest = 19; // our custom mask
-var nResult = createMask.apply(this, arrayFromMask(nTest));
-
-alert(nResult); // 19
-
- -

For the didactic purpose only (since there is the Number.toString(2) method), we show how it is possible to modify the arrayFromMask algorithm in order to create a String containing the binary representation of a Number, rather than an Array of Booleans:

- -
function createBinaryString(nMask) {
-  // nMask must be between -2147483648 and 2147483647
-  for (var nFlag = 0, nShifted = nMask, sMask = ''; nFlag < 32;
-       nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
-  return sMask;
-}
-
-var string1 = createBinaryString(11);
-var string2 = createBinaryString(4);
-var string3 = createBinaryString(1);
-
-alert(string1);
-// prints 00000000000000000000000000001011, i.e. 11
-
- -

規範

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-11.7')}}{{Spec2('ES5.1')}}Defined in several sections of the specification: Bitwise NOT operator, Bitwise shift operators, Binary bitwise operators
{{SpecName('ES6', '#sec-bitwise-shift-operators')}}{{Spec2('ES6')}}Defined in several sections of the specification: Bitwise NOT operator, Bitwise shift operators, Binary bitwise operators
{{SpecName('ESDraft', '#sec-bitwise-shift-operators')}}{{Spec2('ESDraft')}}Defined in several sections of the specification: Bitwise NOT operator, Bitwise shift operators, Binary bitwise operators
- -

瀏覽器相容性

- - - -

{{Compat("javascript.operators.bitwise")}}

- -

另見

- - -- cgit v1.2.3-54-g00ecf