Битовые операторы и операторы сдвига Dart

Работает с каждым битом двоичного представления чисел, используется только для целых чисел

Таблица битовых операторов и операторов сдвига

ОператорНазваниеПравила вычисления
&Побитовое И ANDРезультирующий бит равен 1 только если соответствующие двоичные биты одновременно равны 1, иначе 0
|Побитовое ИЛИ ORРезультирующий бит равен 1, если хотя бы один из соответствующих бит равен 1, иначе 0
^Побитовое XOR (исключающее ИЛИ)Результирующий бит равен 1, если соответствующие двоичные биты разные, при одинаковых значениях бит равен 0
~exprПобитовое инвертирование (унарный оператор)Все двоичные биты меняются местами 0 ↔ 1: 0 превращается в 1, 1 в 0
<<Сдвиг влево Shift leftВся двоичная последовательность сдвигается на N позиций влево, справа добавляются нули
>>Знаковый сдвиг вправо Shift rightДвоичная строка сдвигается на N позиций вправо, слева заполняется бит знака (для положительных чисел 0, для отрицательных 1)
>>>Беззнаковый сдвиг вправо Unsigned shift rightДвоичная строка сдвигается на N позиций вправо, слева всегда подставляются нули; отрицательные числа предварительно преобразуются в беззнаковое 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)

Побитовое XOR (^)

Результирующий бит равен 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); // Инвертируем маску, затем И с 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. Побитовое 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. Беззнаковый сдвиг вправо >>> (отрицательное число, результат всегда больше нуля)
  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
---------
00100000  // 0x20 = 32Code language: JavaScript (javascript)

Строка 11110000 — это результат вычисления ~mask: у исходного 00001111 все биты инвертированы, 0 заменён на 1, 1 на 0.

3 Побитовое ИЛИ |

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

Результат бит равен 1, если хотя бы один из бит равен единице; только при двух нулях результат ноль.

4 Побитовое XOR ^

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

Единица получается только при разных битах сверху и снизу, при одинаковых битах ноль.

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 = (слева заполняем нулями) 00001101...  // результат всегда больше нуляCode language: JavaScript (javascript)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *