1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
|
---
title: 位元運算子
slug: >-
conflicting/Web/JavaScript/Reference/Operators_7c8eb9475d97a4a734c5991857698560
translation_of: Web/JavaScript/Reference/Operators
translation_of_original: Web/JavaScript/Reference/Operators/Bitwise_Operators
original_slug: Web/JavaScript/Reference/Operators/Bitwise_Operators
---
<div>{{jsSidebar("Operators")}}</div>
<p><strong>位元運算子</strong>將運算元視為一段 32 位元長的 0 和 1 序列,而不是十進位、十六進位或八進位的 <code><a href="/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number">Numbers</a></code>。 舉例來說,十進位的 9 可以用二進位表示為 1001。位元運算子對這樣的二進位表示法進行運算,然後回傳標準 JavaScript 數值。</p>
<div>{{EmbedInteractiveExample("pages/js/expressions-bitwiseoperators.html")}}</div>
<p>下表總結了 JavaScript 的位元運算子:</p>
<table class="standard-table">
<tbody>
<tr>
<th>Operator</th>
<th>Usage</th>
<th>Description</th>
</tr>
<tr>
<td><a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#(位元_AND)">位元 AND</a></td>
<td><code>a & b</code></td>
<td>當兩運算元的該位置皆為 <code>1</code> 時,回傳值的該位置為 <code>1</code>。</td>
</tr>
<tr>
<td><a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#(位元_OR)">位元 OR</a></td>
<td><code>a | b</code></td>
<td>當兩運算元的該位置有一者為 <code>1</code> 時,回傳值的該位置為 <code>1</code>。</td>
</tr>
<tr>
<td><a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#(位元_XOR)">位元 XOR</a></td>
<td><code>a ^ b</code></td>
<td>當兩運算元的該位置恰好一者為 <code>1</code> 時,回傳值的該位置為 <code>1</code>。</td>
</tr>
<tr>
<td><a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#(位元_NOT)">位元 NOT</a></td>
<td><code>~ a</code></td>
<td>將運算元的所有位元反轉。</td>
</tr>
<tr>
<td><a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#%3C%3C_(左移)">左移</a></td>
<td><code>a << b</code></td>
<td>將 <code>a</code> 的二進位表示法左移 <code>b</code> (< 32) 位元,右側補 <code>0</code>。</td>
</tr>
<tr>
<td><a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#%3E%3E_(保持符號右移)">保持符號右移</a></td>
<td><code>a >> b</code></td>
<td>將 <code>a</code> 的二進位表示法右移 <code>b</code> (< 32) 位元,拋棄被移出的位元。</td>
</tr>
<tr>
<td><a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#%3E%3E%3E_(填零右移)">填零右移</a></td>
<td><code>a >>> b</code> </td>
<td>將 <code>a</code> 的二進位表示法右移 <code>b</code> (< 32) 位元,拋棄被移出的位元,並於右側補 <code>0</code>。</td>
</tr>
</tbody>
</table>
<h2 id="帶號的_32位元整數">帶號的 32位元整數</h2>
<p>所有位元運算子的運算元皆會被轉換成二<a href="https://en.wikipedia.org/wiki/Method_of_complements">補數系統</a>下的帶號32位元整數。二補數系統意味著一個整數的加法反元素(例如 5和 -5)是該整數的所有位元反轉(位元 NOT,也就是該數的一補數) 再加一。舉例來說,下面的序列代表著整數 314:</p>
<pre class="brush: js">00000000000000000000000100111010
</pre>
<p>下面的序列代表 <code>~314</code>,也就是 <code>314</code> 的一補數:</p>
<pre class="brush: js">11111111111111111111111011000101
</pre>
<p>接著,下面代表著 <code>-314</code>,也就是 <code>314</code> 的二補數:</p>
<pre class="brush: js">11111111111111111111111011000110
</pre>
<p>二補數系統確保了正值時最左邊的位元為 0,反之則為 1。因此,最左邊的位元被稱作符號位。</p>
<p>整數 <code>0</code> 全由位元 0組成。</p>
<pre class="brush: js">0 (base 10) = 00000000000000000000000000000000 (base 2)
</pre>
<p>整數 <code>-1</code> 全由位元 1組成。</p>
<pre class="brush: js">-1 (base 10) = 11111111111111111111111111111111 (base 2)
</pre>
<p>整數 <code>-2147483648</code> (十六進位: <code>-0x80000000</code>) 除了第一位為 1,其餘皆由位元 0組成。</p>
<pre class="brush: js">-2147483648 (base 10) = 10000000000000000000000000000000 (base 2)
</pre>
<p>整數 <code>-2147483648</code> (十六進位: <code>-0x7fffffff</code>) 除了第一位為 0,其餘皆由位元 1組成。</p>
<pre class="brush: js">2147483647 (base 10) = 01111111111111111111111111111111 (base 2)
</pre>
<p>整數 <code>-2147483648</code> 和 <code>2147483647</code> 分別為帶號32位元整數所能表示的最小值和最大值。</p>
<h2 id="位元邏輯運算子">位元邏輯運算子</h2>
<p>大致上,位元邏輯運算子的運作如下︰</p>
<ul>
<li>運算元會被轉換成 32位元的整數,並被表達為一系列的位元 (0 和 1)。多於 32位元的數值在轉換中其超出第32位元的部分會被捨棄。下面的多於32位元整數在被轉換時:
<pre class="brush: js">Before: 11100110111110100000000000000110000000000001
After: 10100000000000000110000000000001</pre>
</li>
<li>兩個運算元中的位元會根據其位置兩兩一組:第一個跟第一個、第二個跟第二個 ...</li>
<li>運算子會作用在每一組位元上,運算完成後再重新組合起來得到回傳值。</li>
</ul>
<h3 id="(位元_AND)"><a id="Bitwise_AND" name="Bitwise_AND">& (位元 AND)</a></h3>
<p>對每一組位元執行 AND 運算。<code>a</code> AND <code>b</code> 只在 <code>a</code> 和 <code>b</code> 同時為 <code>1</code> 時得到 1。AND運算的真值表如下:</p>
<table class="standard-table">
<tbody>
<tr>
<td class="header">a</td>
<td class="header">b</td>
<td class="header">a AND b</td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
</tbody>
</table>
<pre class="brush: js">. 9 (base 10) = 00000000000000000000000000001001 (base 2)
14 (base 10) = 00000000000000000000000000001110 (base 2)
--------------------------------
14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
</pre>
<p>將任何數 <code>x</code> 和 <code>0</code> 做位元 AND 皆會得到 <code>0</code>。將任何數 <code>x</code> 和 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">-1</span></font> 做位元 AND 皆會得到 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">x</span></font>。</p>
<h3 id="(位元_OR)"><a name="Bitwise_OR">| (位元 OR)</a></h3>
<p>對每一組位元執行 OR 運算。<code>a</code> OR <code>b</code> 在 <code>a</code> 和 <code>b</code> 有一者為 <code>1</code> 時得到 1。OR運算的真值表如下:</p>
<table class="standard-table">
<tbody>
<tr>
<td class="header">a</td>
<td class="header">b</td>
<td class="header">a OR b</td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
</tbody>
</table>
<pre class="brush: js">. 9 (base 10) = 00000000000000000000000000001001 (base 2)
14 (base 10) = 00000000000000000000000000001110 (base 2)
--------------------------------
14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
</pre>
<p>將任何數 <code>x</code> 和 <code>0</code> 做位元 OR 皆會得到 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">x</span></font>。將任何數 <code>x</code> 和 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">-1</span></font> 做位元 OR 皆會得到 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">-1</span></font>。</p>
<h3 id="(位元_XOR)"><a name="Bitwise_XOR">^ (位元 XOR)</a></h3>
<p>對每一組位元執行 XOR 運算。<code>a</code> XOR <code>b</code> 只在 <code>a</code> 和 <code>b</code> 恰一者為 <code>1</code> 時得到 1。XOR運算的真值表如下:</p>
<table class="standard-table">
<tbody>
<tr>
<td class="header">a</td>
<td class="header">b</td>
<td class="header">a XOR b</td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>0</td>
</tr>
</tbody>
</table>
<pre class="brush: js">. 9 (base 10) = 00000000000000000000000000001001 (base 2)
14 (base 10) = 00000000000000000000000000001110 (base 2)
--------------------------------
14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
</pre>
<p>將任何數 <code>x</code> 和 <code>0</code> 做位元 AND 皆會得到 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">x</span></font>。將任何數 <code>x</code> 和 <font face="consolas, Liberation Mono, courier, monospace">-1</font> 做位元 AND 皆會得到 <code>~x</code>。</p>
<h3 id="(位元_NOT)"><a name="Bitwise_NOT">~ (位元 NOT)</a></h3>
<p>對每一個位元執行 NOT 運算。NOT <code>a</code> 會得到 <code>a</code> 的反轉值(也就是一補數)。NOT運算的真值表如下:</p>
<table class="standard-table">
<tbody>
<tr>
<td class="header">a</td>
<td class="header">NOT a</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
</tr>
</tbody>
</table>
<pre class="brush: js"> 9 (base 10) = 00000000000000000000000000001001 (base 2)
--------------------------------
~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
</pre>
<p>將任何數 <code>x</code> 做位元 NOT 皆會得到 <code>-(x + 1)</code>。舉例來說,<code>~-5</code> 會得到 <code>4</code>。</p>
<p>值得注意的是,因為使用 32位元表示法表示數值 <code>~-1</code> 和 <code>~4294967295</code> (2<sup>32</sup>-1) 皆會得到 <code>0</code>。</p>
<h2 id="位元位移運算子">位元位移運算子</h2>
<p>位移運算子需要兩個運算元:第一個是要被位移的值,第二個是位元位移量。位移的方向取決於使用的運算子。</p>
<p>位移運算子將運算元轉換成 32位元的大端序整數並回傳一個與左運算元相同類別的值。右運算元應不大於32,如果超過的話,將只會使用後 5個位元。</p>
<h3 id="<<_(左移)"><a name="Left_shift"><< (左移)</a></h3>
<p>將第一個運算元向左位移指定的量。被移出的位元會被拋棄,並從右側補零。</p>
<p>例如,<code>9 << 2</code> 會得到 36:</p>
<pre class="brush: js">. 9 (base 10): 00000000000000000000000000001001 (base 2)
--------------------------------
9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
</pre>
<p>將任意值 <code>x</code> 左移 <code>y</code> 位元會得到 <code>x * 2 ** y</code>。</p>
<h3 id=">>_(保持符號右移)"><a name="Right_shift">>> (保持符號右移)</a></h3>
<p>將第一個運算元向右位移指定的量。被移出的位元會被拋棄,並從左側補進和原本最左端相同的位元值。因為新的最左端位元和原本的最左端位元是一樣的,符號位(最左端位元)並不會改變。「保持符號」之名便是因此。</p>
<p>例如,<code>9 >> 2</code> 會得到 2:</p>
<pre class="brush: js">. 9 (base 10): 00000000000000000000000000001001 (base 2)
--------------------------------
9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
</pre>
<p>同樣地,<code>-9 >> 2</code> 會得到 <code>-3</code>,因為符號會保持不變。</p>
<pre class="brush: js">. -9 (base 10): 11111111111111111111111111110111 (base 2)
--------------------------------
-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
</pre>
<h3 id=">>>_(填零右移)"><a name="Unsigned_right_shift">>>> (填零右移)</a></h3>
<p>將第一個運算元向右位移指定的量。被移出的位元會被拋棄,並從左側補零。因為符號位變成 0,所以結果永遠都是正值。</p>
<p>對非負的數來說,填零右移會得到和保持符號右移一樣的結果。例如,<code>9 >>> 2</code> 和 <code>9 >> 2</code> 一樣,皆會得到 2:</p>
<pre class="brush: js">. 9 (base 10): 00000000000000000000000000001001 (base 2)
--------------------------------
9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
</pre>
<p>然而對負值來說並不是這麼一回事。例如,<code>-9 >>> 2</code> 會得到 1073741821,跟 <code>-9 >> 2</code> (得到 <code>-3</code>)的結果是不一樣的:</p>
<pre class="brush: js">. -9 (base 10): 11111111111111111111111111110111 (base 2)
--------------------------------
-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
</pre>
<h2 id="範例">範例</h2>
<h3 id="旗標(flags)_和遮罩_(bitmasks)">旗標(flags) 和遮罩 (bitmasks)</h3>
<p>位元運算子常被用於生成、修改、和讀取旗標序列,就像是二進制的變數一般。雖然也可以使用普通變數,但使用二進制的旗標序列大大的減少了所需空間 (32 倍)。</p>
<p>假設有 4個旗標:</p>
<ul>
<li>旗標 A:我們有螞蟻問題</li>
<li>旗標 B:我們擁有一隻蝙蝠</li>
<li>旗標 C:我們擁有一隻貓</li>
<li>旗標 D:我們擁有一隻鴨子</li>
</ul>
<p>這些旗標倍表達成一個位元序列:DCBA。當一個旗標被立起 (set)時,其值為1。當一個旗標被放下 (clear),其值為0。假設有一變數 <code>flags</code> 的二進位值為 0101:</p>
<pre class="brush: js">var flags = 5; // 二進位 0101
</pre>
<p>這個值表示:</p>
<ul>
<li>旗標 A為真 (我們有螞蟻問題);</li>
<li>旗標 B為假 (我們並未擁有一隻蝙蝠);</li>
<li>旗標 C為真 (我們擁有一隻貓);</li>
<li>旗標 D為假 (我們並未擁有一隻鴨子);</li>
</ul>
<p>因為位元運算子進行的是 32位元操作,0101 實際上是 00000000000000000000000000000101,但前導的 0可被忽略因為他們沒有實際上的意義。</p>
<p>位元遮罩則為一個可以修改且(或)讀取旗標序列的位元序列。通常為每個單獨旗標為真的「初始」值:</p>
<pre class="brush: js">var FLAG_A = 1; // 0001
var FLAG_B = 2; // 0010
var FLAG_C = 4; // 0100
var FLAG_D = 8; // 1000
</pre>
<p>新的位元遮罩可以透過對初始遮罩進行位元運算獲得。例如,遮罩 1011 可以透過對 FLAG_A、FLAG_B、和 FLAG_D進行 OR運算獲得:</p>
<pre class="brush: js">var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
</pre>
<p>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 <em>masks</em> 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:</p>
<pre class="brush: js">// if we own a cat
if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
// do stuff
}
</pre>
<p>A bitmask with multiple set flags acts like an "either/or". For example, the following two are equivalent:</p>
<pre class="brush: js">// 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
}
</pre>
<pre class="brush: js">// 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
}
</pre>
<p>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:</p>
<pre class="brush: js">// yes, we own a cat and a duck
var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
flags |= mask; // 0101 | 1100 => 1101
</pre>
<p>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:</p>
<pre class="brush: js">// 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
</pre>
<p>The mask could also have been created with <code>~FLAG_A & ~FLAG_C</code> (De Morgan's law):</p>
<pre class="brush: js">// 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
</pre>
<p>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:</p>
<pre class="brush: js">// 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
</pre>
<p>Finally, the flags can all be flipped with the NOT operator:</p>
<pre class="brush: js">// entering parallel universe...
flags = ~flags; // ~1010 => 0101
</pre>
<h3 id="Conversion_snippets">Conversion snippets</h3>
<p>Convert a binary <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String" title="/en-US/docs/JavaScript/Reference/Global_Objects/String">String</a></code> to a decimal <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number">Number</a></code>:</p>
<pre class="brush: js">var sBinString = '1011';
var nMyNumber = parseInt(sBinString, 2);
alert(nMyNumber); // prints 11, i.e. 1011
</pre>
<p>Convert a decimal <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number">Number</a></code> to a binary <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String" title="/en-US/docs/JavaScript/Reference/Global_Objects/String">String</a></code>:</p>
<pre class="brush: js">var nMyNumber = 11;
var sBinString = nMyNumber.toString(2);
alert(sBinString); // prints 1011, i.e. 11
</pre>
<h3 id="Automate_Mask_Creation">Automate Mask Creation</h3>
<p>You can create multiple masks from a set of <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean" title="/en-US/docs/JavaScript/Reference/Global_Objects/Boolean">Boolean</a></code> values, like this:</p>
<pre class="brush: js">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
</pre>
<h3 id="Reverse_algorithm_an_array_of_booleans_from_a_mask">Reverse algorithm: an array of booleans from a mask</h3>
<p>If you want to create an <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array" title="/en-US/docs/JavaScript/Reference/Global_Objects/Array">Array</a></code> of <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean" title="/en-US/docs/JavaScript/Reference/Global_Objects/Boolean">Booleans</a></code> from a mask you can use this code:</p>
<pre class="brush: js">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
</pre>
<p>You can test both algorithms at the same time…</p>
<pre class="brush: js">var nTest = 19; // our custom mask
var nResult = createMask.apply(this, arrayFromMask(nTest));
alert(nResult); // 19
</pre>
<p>For the didactic purpose only (since there is the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number/toString">Number.toString(2)</a></code> method), we show how it is possible to modify the <code>arrayFromMask</code> algorithm in order to create a <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String" title="/en-US/docs/JavaScript/Reference/Global_Objects/String">String</a></code> containing the binary representation of a <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/JavaScript/Reference/Global_Objects/Number">Number</a></code>, rather than an <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array" title="/en-US/docs/JavaScript/Reference/Global_Objects/Array">Array</a></code> of <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean" title="/en-US/docs/JavaScript/Reference/Global_Objects/Boolean">Booleans</a></code>:</p>
<pre class="brush: js">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
</pre>
<h2 id="規範">規範</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td>{{SpecName('ES1')}}</td>
<td>{{Spec2('ES1')}}</td>
<td>Initial definition.</td>
</tr>
<tr>
<td>{{SpecName('ES5.1', '#sec-11.7')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.4.8">Bitwise NOT operator</a>, <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.7">Bitwise shift operators</a>, <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-11.10">Binary bitwise operators</a></td>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-bitwise-shift-operators')}}</td>
<td>{{Spec2('ES6')}}</td>
<td>Defined in several sections of the specification: <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-bitwise-not-operator">Bitwise NOT operator</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-bitwise-shift-operators">Bitwise shift operators</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-binary-bitwise-operators">Binary bitwise operators</a></td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-bitwise-shift-operators')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td>Defined in several sections of the specification: <a href="http://tc39.github.io/ecma262/#sec-bitwise-not-operator">Bitwise NOT operator</a>, <a href="http://tc39.github.io/ecma262/#sec-bitwise-shift-operators">Bitwise shift operators</a>, <a href="http://tc39.github.io/ecma262/#sec-binary-bitwise-operators">Binary bitwise operators</a></td>
</tr>
</tbody>
</table>
<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
<div class="hidden">
<p>The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p>
</div>
<p>{{Compat("javascript.operators.bitwise")}}</p>
<h2 id="另見">另見</h2>
<ul>
<li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators">Logical operators</a></li>
</ul>
|