Dart ビット演算子とシフト演算子

数値の2進数の各ビットを操作し、整数にのみ使用します

ビット演算子・シフト演算子一覧表

演算子名称演算ルール
&ビットAND対応する2進ビットが両方1の場合のみ結果ビットが1、それ以外は0
|ビットOR対応する2進ビットのいずれか一方が1なら結果ビットが1、両方0のみ0
^ビットXOR(排他的論理和)対応する2進ビットが異なる値の場合1、同じ値なら0
~exprビット反転(単項演算子)全ての2進ビットを0⇔1反転、0は1に、1は0になる
<<左シフト Shift left2進全体をNビット左に移動、右側に0を補填
>>符号付き右シフト Shift right2進全体をNビット右に移動、左側に符号ビットを補填(正数は0、負数は1)
>>>符号なし右シフト Unsigned shift right2進全体をNビット右に移動、左側に一律0を補填;負数は事前に32ビット符号なし整数に変換後シフト

ビットAND演算子(&

対応する2つのビットが両方1のときのみ結果ビットが1、どちらか一方でも0なら結果は0になります。

1番目の数値(ビット)2番目の数値(ビット)演算結果
111
100
010
000

void main() {
  // 1ビット単体演算検証
  assert((1 & 1) == 1);
  assert((1 & 0) == 0);
  assert((0 & 1) == 0);
  assert((0 & 0) == 0);

  // 複数ビット整数演算例
  final a = 0x22; // 2進 00100010
  final b = 0x0f; // 2進 00001111
  assert((a & b) == 0x02); // 結果 00000010
}Code language: PHP (php)

ビットOR演算子(|

対応する2つのビットのうちどちらか一方が1なら結果ビットは1、両方0の場合のみ結果が0となります。

1番目の数値(ビット)2番目の数値(ビット)演算結果
111
101
011
000
void main() {
  // 1ビット単体演算検証
  assert((1 | 1) == 1);
  assert((1 | 0) == 1);
  assert((0 | 1) == 1);
  assert((0 | 0) == 0);

  // 複数ビット整数演算例
  final a = 0x22; // 2進 00100010
  final b = 0x0f; // 2進 00001111
  assert((a | b) == 0x2f); // 結果 00101111
}Code language: PHP (php)

ビットXOR演算子(^

対応する2つのビットの値が異なる場合結果ビットは1、同じ値なら0になります。

1番目の数値(ビット)2番目の数値(ビット)演算結果
110
101
011
000

void main() {
  // 1ビット単体演算検証
  assert((1 ^ 1) == 0);
  assert((1 ^ 0) == 1);
  assert((0 ^ 1) == 1);
  assert((0 ^ 0) == 0);

  // 複数ビット整数演算例
  final a = 0x22; // 2進 00100010
  final b = 0x0f; // 2進 00001111
  assert((a ^ b) == 0x2d); // 結果 00101101
}Code language: PHP (php)

ビット反転演算子(~

単項演算子でオペランドが1つだけ必要、2進ビットを1ビットごとに反転:0→1、1→0。

元のビット反転後ビット
10
01

void main() {
  // 1ビット単体演算検証
  assert((~1 & 1) == 0);
  assert((~0 & 1) == 1);

  // 複数ビット整数演算例
  final a = 0x22; // 2進 00100010
  final mask = 0x0f; // 2進 00001111
  assert((a & ~mask) == 0x20); // maskを反転後AND、下位4ビットをクリア
}Code language: PHP (php)

実例全体を確認

void main() {
  // テスト用数値定義
  final value = 0x22;   // 16進 0x22 = 10進 34、2進 00100010
  final bitmask = 0x0f; // 16進 0x0f = 10進 15、2進 00001111

  // 1. ビットAND &
  print('value & bitmask = ${value & bitmask}'); // 0x02 = 2
  assert((value & bitmask) == 0x02);

  // 2. 反転マスクとAND(& ~mask、下位ビット消去に頻出)
  print('value & ~bitmask = ${value & ~bitmask}'); // 0x20 = 32
  assert((value & ~bitmask) == 0x20);

  // 3. ビットOR |
  print('value | bitmask = ${value | bitmask}'); // 0x2f = 47
  assert((value | bitmask) == 0x2f);

  // 4. ビットXOR ^
  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つずつ分解解説

1 ビットAND
00100010
00001111
--------
00000010

最終結果は00000010、10進数で2となります。

2 反転マスク付きビットAND & ~mask
00100010
11110000  // ~00001111
---------
00100000  // 0x20 = 32Code language: JavaScript (javascript)

11110000 は ~mask の演算結果:元の00001111の全ビットを反転、0が1に、1が0に切り替わる

3 ビットOR |

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

どちらか一方のビットが1なら結果は1、両方0の場合のみ0になる

4 ビットXOR ^

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...  // 結果は必ず0より大きいCode language: JavaScript (javascript)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です