用來操作數字的二進制每一個位元,僅能搭配整數使用
位元運算子與移位運算子一覽表
| 運算子 | 名稱 | 運算規則 |
|---|---|---|
& | 位元且 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。
| 第一個數字(單個位元) | 第二個數字(單個位元) | 運算結果 |
|---|---|---|
| 1 | 1 | 1 |
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 0 | 0 |
範例
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。
| 第一個數字(單個位元) | 第二個數字(單個位元) | 運算結果 |
|---|---|---|
| 1 | 1 | 1 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
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。
| 第一個數字(單個位元) | 第二個數字(單個位元) | 運算結果 |
|---|---|---|
| 1 | 1 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
範例
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。
| 原始位元 | 取反後結果 |
|---|---|
| 1 | 0 |
| 0 | 1 |
範例
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)
Previous: Dart 邏輯運算子
Next: Dart 條件運算式