Dart 位元運算子與移位運算子

用來操作數字的二進制每一個位元,僅能搭配整數使用

位元運算子與移位運算子一覽表

運算子名稱運算規則
&位元且 AND對應的二進位元同時為 1,結果位元才是 1,否則為 0
|位元或 OR對應的二進位元任一為 1,結果位元就是 1,否則為 0
^位元互斥或 XOR對應的二進位元數值不同則為 1,數值相同則為 0
~運算式位元取反(一元運算子)所有二進位元 0 ↔ 1,0 轉 1、1 轉 0
<<位元左移 Shift left整組二進制往左平移 N 個位元,右側空出處補 0
>>有符號右移 Shift right整組二進制往右平移 N 個位元,左側補上符號位(正數補 0、負數補 1)
>>>無符號右移 Unsigned shift right整組二進制往右平移 N 個位元,左側一律補 0;負數會先轉為無符號32位整數再執行移位

位元且運算子(&

兩個對應的二進位元同時為 1時,結果位元為 1;其餘狀況結果皆為 0。

第一個數字(單個位元)第二個數字(單個位元)運算結果
111
100
010
000

範例

void main() {
  // 單一位元運算驗證
  assert((1 & 1) == 1);
  assert((1 & 0) == 0);
  assert((0 & 1) == 0);
  assert((0 & 0) == 0);

  // 多位元整數運算範例
  final a = 0x22; // 二進制 00100010
  final b = 0x0f; // 二進制 00001111
  assert((a & b) == 0x02); // 運算結果 00000010
}Code language: PHP (php)

位元或運算子(|

兩個對應的二進位元任一為 1時,結果位元為 1;只有兩者皆為 0 才會得到 0。

第一個數字(單個位元)第二個數字(單個位元)運算結果
111
101
011
000
void main() {
  // 單一位元運算驗證
  assert((1 | 1) == 1);
  assert((1 | 0) == 1);
  assert((0 | 1) == 1);
  assert((0 | 0) == 0);

  // 多位元整數運算範例
  final a = 0x22; // 二進制 00100010
  final b = 0x0f; // 二進制 00001111
  assert((a | b) == 0x2f); // 運算結果 00101111
}Code language: PHP (php)

位元互斥或運算子(^

兩個對應的二進位元數值不相同時,結果位元為 1;數值相同則結果為 0。

第一個數字(單個位元)第二個數字(單個位元)運算結果
110
101
011
000

範例

void main() {
  // 單一位元運算驗證
  assert((1 ^ 1) == 0);
  assert((1 ^ 0) == 1);
  assert((0 ^ 1) == 1);
  assert((0 ^ 0) == 0);

  // 多位元整數運算範例
  final a = 0x22; // 二進制 00100010
  final b = 0x0f; // 二進制 00001111
  assert((a ^ b) == 0x2d); // 運算結果 00101101
}Code language: PHP (php)

位元取反運算子(~

一元運算子,只需要一個運算元,對所有二進位元逐位反向:0 轉為 1,1 轉為 0。

原始位元取反後結果
10
01

範例

void main() {
  // 單一位元運算驗證
  assert((~1 & 1) == 0);
  assert((~0 & 1) == 1);

  // 多位元整數運算範例
  final a = 0x22; // 二進制 00100010
  final mask = 0x0f; // 二進制 00001111
  assert((a & ~mask) == 0x20); // 將mask取反後與a做位元且,用來清空低4位元
}Code language: PHP (php)

完整綜合示範

void main() {
  // 定義測試數值
  final value = 0x22;   // 十六進制 0x22 = 十進制 34,二進制 00100010
  final bitmask = 0x0f; // 十六進制 0x0f = 十進制 15,二進制 00001111

  // 1. 位元且 &
  print('value & bitmask = ${value & bitmask}'); // 0x02 = 2
  assert((value & bitmask) == 0x02);

  // 2. 位元且搭配取反(& ~mask 常用於清空低位元)
  print('value & ~bitmask = ${value & ~bitmask}'); // 0x20 = 32
  assert((value & ~bitmask) == 0x20);

  // 3. 位元或 |
  print('value | bitmask = ${value | bitmask}'); // 0x2f = 47
  assert((value | bitmask) == 0x2f);

  // 4. 位元互斥或 ^
  print('value ^ bitmask = ${value ^ bitmask}'); // 0x2d = 45
  assert((value ^ bitmask) == 0x2d);

  // 5. 位元左移 <<
  print('value << 4 = ${value << 4}'); // 0x220 = 544
  assert((value << 4) == 0x220);

  // 6. 有符號右移 >>(正數範例)
  print('value >> 4 = ${value >> 4}'); // 0x02 = 2
  assert((value >> 4) == 0x02);

  // 7. 有符號右移 >>(負數,不同平台行為一致)
  print('-value >> 4 = ${-value >> 4}'); // -0x03 = -3
  assert((-value >> 4) == -0x03);

  // 8. 無符號右移 >>>(正數,Dart2.14以上支援)
  print('value >>> 4 = ${value >>> 4}'); // 0x02 = 2
  assert((value >>> 4) == 0x02);

  // 9. 無符號右移 >>>(負數,運算結果必定大於0)
  print('-value >>> 4 = ${-value >>> 4}');
  assert((-value >>> 4) > 0);
}Code language: PHP (php)

程式執行輸出

D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
value & bitmask = 2
value & ~bitmask = 32
value | bitmask = 47
value ^ bitmask = 45
value << 4 = 544
value >> 4 = 2
-value >> 4 = -3
value >>> 4 = 2
-value >>> 4 = 1152921504606846973

逐項拆解上面的示範程式

1 位元且運算
00100010
00001111
--------
00000010

最終運算結果為 00000010,對應十進制數字 2

2 位元且搭配取反 & ~mask
00100010
11110000  // ~00001111 的取反結果,0變1、1變0
---------
00100000  // 等同 0x20 = 32Code language: JavaScript (javascript)

上面的 11110000 是 ~mask 將 00001111 逐位取反後的數值,所有位元0、1互換。

3 位元或 |

00100010
00001111
---------
00101111  // 等同 0x2f = 47Code language: JavaScript (javascript)

只要任一對應位元是1,結果位元就是1;只有兩個位元同時為0才會得到0。

4 位元互斥或 ^

00100010
00001111
---------
00101101  // 等同 0x2d = 45Code language: JavaScript (javascript)

上下兩個位元數值不同,結果才是1;數值相同則結果為0。

5 位元左移 << 4

00100010 << 4 = 001000100000
運算結果:0x220 = 544

6 有符號右移 >> 4 (正數)

00100010 >> 4 = 00000010
運算結果:0x02 = 2

7 有符號右移 >> 4(負數)

-00100010 >> 4 = -00000011
運算結果:-0x03 = -3

8 無符號右移 >>> 4(正數)

00100010 >>> 4 = 00000010
運算結果:0x02 = 2

9 無符號右移 >>> 4(負數)

-00100010 >>> 4 = (左側高位一律補0)00001101...  // 運算結果一定大於0Code language: JavaScript (javascript)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *