From 074785cea106179cb3305637055ab0a009ca74f2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:52 -0500 Subject: initial commit --- .../operators/bitwise_operators/index.html | 625 +++++++++++++++++++++ 1 file changed, 625 insertions(+) create mode 100644 files/ru/web/javascript/reference/operators/bitwise_operators/index.html (limited to 'files/ru/web/javascript/reference/operators/bitwise_operators') diff --git a/files/ru/web/javascript/reference/operators/bitwise_operators/index.html b/files/ru/web/javascript/reference/operators/bitwise_operators/index.html new file mode 100644 index 0000000000..e681bdf40b --- /dev/null +++ b/files/ru/web/javascript/reference/operators/bitwise_operators/index.html @@ -0,0 +1,625 @@ +--- +title: Битовые операции +slug: Web/JavaScript/Reference/Operators/Bitwise_Operators +tags: + - JavaScript + - Оператор +translation_of: Web/JavaScript/Reference/Operators +--- +
{{jsSidebar("Operators")}}
+ +

Сводка

+ +

Битовые операции обращаются со своими операндами как с 32-х разрядными последовательностями нулей и единиц, а не как с десятичными, восьмеричными или шестнадцатиричными числами. К примеру десятичное число 9 в двоичном представлении будет выглядеть как 1001. Битовые операции производят свои преобразования именно с двоичным представлением числа, но возвращают стандартные числовые значения языка JavaScript.

+ + + + + + + + + + + + + + + +
Операторы
Реализованы в:JavaScript 1.0
Версия ECMA:ECMA-262
+ +

Следующая таблица содержит сводные данные о битовых операциях в JavaScript:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ОператорИспользованиеОписание
Побитовое Иa & bВозвращает 1 в тех разрядах, которые у обоих операндов были равны 1.
Побитовое ИЛИa | bВозвращает 1 в тех разрядах, которые хотя бы у одного из операндов были равны 1.
Побитовое исключающее ИЛИa ^ bВозвращает 1 в тех позициях, которые только у одного из операндов были равны 1.
Побитовое НЕ~ aИнвертирует биты операнда.
Сдвиг влевоa << bСдвигает двоичное представление числа a на b разрядов влево заполняя освободившиеся справа разряды нулями.
Арифметический сдвиг вправоa >> bСдвигает двоичное представление числа a на b разрядов вправо. Освобождающиеся разряды заполняются  знаковым битом.
Логический сдвиг вправоa >>> bСдвигает двоичное представление числа a на b разрядов вправо. Освобождающиеся разряды заполняются нулями.
+ +

Представление чисел (Signed 32-bit integers)

+ +

Операнды всех битовых операций конвертируются в 32-х битовые целые со знаком представленные в дополнительном коде и с использованием порядка битов от "старшего к младшему". Порядок битов "от старшего к младшему" означает, что наиболее значимый бит (бит с наибольшим значением) находится слева если 32-х разрядное число представлено в виде горизонтальной линии (шкалы). Представление в дополнительном коде  означает, что отрицательное значение числа (например 5 и -5) получается путем инвертирования числа (операция "побитовое НЕ", также известное как "обратный код") и прибавления к нему единицы.

+ +

Возьмем, к примеру, число 314. Представим его в двоичном коде:

+ +
00000000000000000000000100111010
+
+ +

Следующая строка представляет собой его обратный код или ~314:

+ +
11111111111111111111111011000101
+
+ +

Прибавив к нему единицу, мы получаем двоичное представление числа  -314, оно же 314 в дополнительном коде:

+ +
11111111111111111111111011000110
+ +

Дополнение до 2-х гарантирует нам, что у положительного числа самый левый бит равен 0, в то время как у отрицательного он равен 1. Он зовется знаковым битом.

+ +


+ Число 0 есть число, у которого во ввсех битовых позициях записаны нули.

+ +
0 (base 10) = 00000000000000000000000000000000 
+ +

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

+ +
-1 (base 10) = 11111111111111111111111111111111 
+ +

Число -2147483648 (в шестнадцатиричной системе счисления: -0x80000000) - это вещественное число, которое состоит только из 0, заисключением самого первого слева, который есть 1 (отвечает за знак числа).

+ +
-2147483648 (base 10) = 10000000000000000000000000000000
+ +

Число 2147483648 (в шестнадцатиричной системе счисления: 0x80000000) - это вещественное число, которое состоит только из 1, заисключением самого первого слева, который есть 0 (отвечает за знак числа).

+ +
2147483647 (base 10) = 01111111111111111111111111111111
+ +

-2147483648 и 2147483647 - это самое минимальное и самое максимальное числа, которые можно представить в 32 разрядной ячейке памяти.

+ +

Побитовые логические операции

+ +

Побитовые логические операции работают следующим образом:

+ + + +
До:         11100110111110100000000000000110000000000001
+После:      10100000000000000110000000000001
+
+ + + +

& (Побитовое AND)

+ +

Производит побитовое И над каждой парой битов. Операция a AND b веренет 1 если только и a и b равны 1. Таблица истинности для этой операции выглядит так:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba AND b
000
010
100
111
+ +

Пример:

+ +
     9 (основание 10) = 00000000000000000000000000001001 (основание 2)
+    14 (основание 10) = 00000000000000000000000000001110 (основание 2)
+                   --------------------------------
+14 & 9 (основание 10) = 00000000000000000000000000001000 (осн. 2) = 8 (осн. 10)
+
+ +

Побитовое  AND любого числа x с нулем вернет 0.

+ +

Побитовое  AND любого числа x с числом -1 вернет х.

+ +

| (Побитовое OR)

+ +

Производит побитовое ИЛИ над каждой парой битов. Операция a OR b веренет 1 если a или b равны 1. Таблица истинности для этой операции выглядит так:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba OR b
000
011
101
111
+ +
Пример:
+
+9 (осн. 10) = 00000000000000000000000000001001 (осн. 2)
+14 (осн. 10) = 00000000000000000000000000001110 (осн. 2)
+                   --------------------------------
+14 | 9 (осн. 10) = 00000000000000000000000000001111 (осн. 2) = 15 (осн. 10)
+
+ +

Побитовое OR любого числа x c нулем вернет x.

+ +

Побитовое OR любого числа x с числом -1 вернет -1.

+ +

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

+ +

Производит побитовое XOR над каждой парой битов. Операция a XOR b вернет 1 если a  и b различны. Таблица истинности для этой операции выглядит так:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba XOR b
000
011
101
110
+ +

Пример:

+ +
     9 (осн. 10) = 00000000000000000000000000001001 (осн. 2)
+    14 (осн. 10) = 00000000000000000000000000001110 (осн. 2)
+                   --------------------------------
+14 ^ 9 (осн. 10) = 00000000000000000000000000000111 (осн. 2) = 7 (осн. 10)
+
+ +

Побитовое XOR любого числа x c нулем вернет x.

+ +

Побитовое XOR любого числа x c числом -1 вернет ~x.

+ +

~ (Побитовое NOT)

+ +

Производит операцию NOT над каждым битом. NOT a вернет побитово инвертированное значение (обратный код) операнда. Таблица истинности для этой операции выглядит так:

+ + + + + + + + + + + + + + + + +
aNOT a
01
10
+ +

Пример:

+ +
 9 (осн. 10) = 00000000000000000000000000001001 (осн. 2)
+               --------------------------------
+~9 (осн. 10) = 11111111111111111111111111110110 (осн. 2) = -10 (осн. 10)
+
+ +

Побитовое NOT любого числа x вернет -(x + 1). Например, ~5 вернет -6.

+ +

Побитовые операции сдвига

+ +

Оператор побитового сдвига принимает в себя два операнда: первый - величина, которую сдвигают, второй - число позиций, на которое сдвигаются биты первого операнда. Направление сдвига зависит от используемого оператора.

+ +

Операторы сдвига конвертируют операнды в 32-ух разрядные числа с порядком байтов от старшего к младшему, а результат возвращает того же типа, что и левый операнд.

+ +

<< (Сдвиг влево)

+ +

Оператор побитового сдвига влево сдвигает первый операнд на заданное число битов влево. Лишние биты отбрасываются.

+ +

Например, 9 << 2 в результате даст 36:

+ +
     9 (осн. 10): 00000000000000000000000000001001 (осн. 2)
+                  --------------------------------
+9 << 2 (осн. 10): 00000000000000000000000000100100 (осн. 2) = 36 (осн. 10)
+
+
+
+ +

Побитовй сдвиг любого числа x влево на y бит в результате дает  x * 2 ** y.

+ +

>> (Сдвиг вправо с сохранением знака)

+ +

Оператор побитового сдвига вправо сдвигает первый операнд на заданное число битов вправо. Лишние биты отбрасываются. Слева добавляется заданное число битов равных первому биту исходного числа. Поскольку значение первого бита, определяющего знак числа, останется неизменным, знак получившегося результата будет таким же как у первого аргумента. Отсюда "с сохранением знака" в названи.

+ +

Например, 9 >> 2 в результате даст 2:

+ +
     9 (осн. 10): 00000000000000000000000000001001 (осн. 2)
+                  --------------------------------
+9 >> 2 (осн. 10): 00000000000000000000000000000010 (осн. 2) = 2 (осн. 10)
+
+ +

Аналогично, -9 >> 2 даст в результате  -3, так как знак сохранен:

+ +
     -9 (осн. 10): 11111111111111111111111111110111 (осн. 2)
+                   --------------------------------
+-9 >> 2 (осн. 10): 11111111111111111111111111111101 (осн. 2) = -3 (осн. 10)
+
+ +

>>> (Сдвиг вправо с заполнением нулями)

+ +

Оператор побитового сдвига вправо сдвигает первый операнд на заданное число битов вправо. Лишние биты отбрасываются. Слева добавляется заданное число нулевых битов. Поскольку значение первого бита, определяющего знак числа, становится нулевым, результатом операции всегда будет положительное число.

+ +

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

+ +

Например, 9 >>> 2 дает в результате 2, как и 9 >> 2:

+ +
      9 (осн. 10): 00000000000000000000000000001001 (осн. 2)
+                   --------------------------------
+9 >>> 2 (осн. 10): 00000000000000000000000000000010 (осн. 2) = 2 (осн. 10)
+
+ +

Важно отметить, что для отрицательных результаты будут разными. Например, -9 >>> 2 дает в результате 1073741821, что отличается от результата -9 >> 2 (равно -3):

+ +
      -9 (осн. 10): 11111111111111111111111111110111 (осн. 2)
+                    --------------------------------
+-9 >>> 2 (осн. 10): 00111111111111111111111111111101 (осн. 2) = 1073741821 (осн. 10)
+
+ +

Примеры

+ +

Пример: флаги и битовые маски

+ +

Побитовые логические операторы часто используются для создания, обработки и чтения последовательности флагов, которые осуществляются также, как и двоичные переменные. Переменные могут быть использованы вместо этих последовательностей, но двоичные флаги занимают гораздо меньше памяти (в 32 разрядной ячейке памяти).

+ +

Предположим, существует 4 флага:

+ + + +

Эти флаги представлены последовательностью битов: DCBA. Считается, что флаг установлен (the flag is set), если его значение равно 1. Флаг сброшен (the flag is cleared), если его значение равно 0. Предположим, что переменная flags содержит двоичное значение 0101:

+ +
var flags = 0x5;   // двоичное 0101
+
+ +

Из этого значения следует:

+ + + +

Так как битовые операторы 32-битные, то 0101 в действительности представлено значением 00000000000000000000000000000101, но ведущие нули могут быть опущены, потому, что не содержат значимой информации.

+ +

Битовая маска, это последовательность битов, которая позволяет манипулировать и/или считывать значения флагов. Обычно для каждого флага задаётся "примитивная" битовая маска:

+ +
var FLAG_A = 0x1; // 0001
+var FLAG_B = 0x2; // 0010
+var FLAG_C = 0x4; // 0100
+var FLAG_D = 0x8; // 1000
+
+ +

New bitmasks can be created by using the bitwise logical operators on these primitive bitmasks. For example, the bitmask 1011 can be created by ORing FLAG_A, FLAG_B, and FLAG_D:

+ +
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
+
+ +

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 masks out the non-relevant flags by ANDing with zeros (hence the term "bitmask"). For example, the bitmask 0100 can be used to see if flag C is set:

+ +
// if we own a cat
+if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
+   // do stuff
+}
+
+ +

A bitmask with multiple set flags acts like an "either/or". For example, the following two are equivalent:

+ +
// if we own a bat or we own a cat
+if ((flags & FLAG_B) || (flags & FLAG_C)) { // (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true
+   // do stuff
+}
+
+ +
// 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
+}
+
+ +

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 1010 can be used to set flags C and D:

+ +
// yes, we own a cat and a duck
+var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
+flags |= mask;   // 0101 | 1100 => 1101
+
+ +

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:

+ +
// no, we don't neither have an ant problem nor own a cat
+var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010
+flags &= mask;   // 1101 & 1010 => 1000
+
+ +

The mask could also have been created with ~FLAG_A & ~FLAG_C (De Morgan's law):

+ +
// 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
+
+ +

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:

+ +
// 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
+
+ +

Finally, the flags can all be flipped with the NOT operator:

+ +
// entering parallel universe...
+flags = ~flags;    // ~1010 => 0101
+
+
+ +

Совместимость с браузерами

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ВозможностьChromeFirefox (Gecko)Internet ExplorerOperaSafari
Битовый NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Сдвиг влево (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Сдвиг вправо (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Беззнаковый сдвиг вправо (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ВозможностьAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Битовый NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Битовый XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Сдвиг влево (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Сдвиг вправо (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Беззнаковый сдвиг вправо (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

Смотрите также

+ + -- cgit v1.2.3-54-g00ecf