--- title: Бітові оператори slug: >- conflicting/Web/JavaScript/Reference/Operators_7c8eb9475d97a4a734c5991857698560 tags: - JavaScript - Довідка - Оператор translation_of: Web/JavaScript/Reference/Operators translation_of_original: Web/JavaScript/Reference/Operators/Bitwise_Operators original_slug: Web/JavaScript/Reference/Operators/Bitwise_Operators ---
Бітові оператори опрацьовують свої операнди як послідовність 32-х бітів (нулів та одиниць), а не як десяткові, шістнадцяткові чи вісімкові числа
. Наприклад, десяткове число дев'ять має бітове представлення 1001. Бітові оператори виконують операції над цими бітовими представленнями, але повертають стандартні числові значення JavaScript.
Наступна таблиця наводить перелік бітових операторів JavaScript:
Оператор | Застосування | Опис |
---|---|---|
Побітове І (AND) | a & b |
Повертає 1 на кожній позиції, де відповідні біти обох операндів дорівнюють 1 . |
Побітове АБО (OR) | a | b |
Повертає 1 на кожній позиції, де відповідні біти одного чи обох операндів дорівнюють 1 . |
Виключне побітове АБО (XOR) | a ^ b |
Повертає 1 на кожній позиції, де відповідний біт одного з двох, але не обох, операндів дорівнює 1 . |
Побітове НЕ (NOT) | ~ a |
Виконує інверсію бітів операнду. |
Лівий зсув | a << b |
Зсуває a у двійковому представленні на b (< 32) бітів ліворуч, заповнюючи позиції справа нулями. |
Правий зсув з розширенням знаку | a >> b |
Зсуває a у двійковому представленні на b (< 32) бітів праворуч, відкидаючи зсунуті біти. |
Правий зсув із заповненням нулями | a >>> b |
Зсуває a у двійковому представленні на b (< 32) бітів праворуч, відкидаючи зсунуті біти та заповнюючи позиції зліва нулями. |
Операнди усіх бітових операторів перетворюються на 32-бітні цілі числа зі знаком у форматі доповняльного коду, окрім оператора правого зсуву із заповненням нулями, який повертає беззнакове ціле 32-бітне число. Формат доповняльного коду означає, що від'ємний еквівалент числа (наприклад, 5 та -5) - це інвертовані біти числа (побітове НЕ, або обернений код числа) плюс один. Для прикладу, наступний код представляє ціле число 314:
00000000000000000000000100111010
Наступний код представляє ~314
, тобто, обернений код числа 314
:
11111111111111111111111011000101
Нарешті, наступний код представляє доповняльний код числа -314
:
11111111111111111111111011000110
Доповняльний код гарантує, що лівий біт дорівнює 0, коли число є додатним, і 1, коли число є від'ємним. Тому він відомий як знаковий біт.
Число 0
є цілим числом, усі біти якого дорівнюють 0.
0 (основа 10) = 00000000000000000000000000000000 (основа 2)
Число -1
є цілим числом, усі біти якого дорівнюють 1.
-1 (основа 10) = 11111111111111111111111111111111 (основа 2)
Число -2147483648
(шістнадцяткове представлення: -0x80000000
) є цілим числом, усі біти якого дорівнюють 0, окрім першого (старшого) біта.
-2147483648 (основа 10) = 10000000000000000000000000000000 (основа 2)
Число 2147483647
(шістнадцяткове представлення: 0x7fffffff
) є цілим числом, усі біти якого дорівнюють 1, окрім першого (старшого) біта.
2147483647 (основа 10) = 01111111111111111111111111111111 (основа 2)
Числа -2147483648
та 2147483647
є мінімальним та максимальним цілими числами, які можуть бути представлені 32-бітним знаковим числом.
Концептуально побітові логічні оператори працюють наступним чином:
До: 11100110111110100000000000000110000000000001 Після: 10100000000000000110000000000001
Виконує операцію І (AND) над кожною парою бітів. a
І b
дає 1 тільки якщо обидва, a
та b
, дорівнюють 1
. Таблиця істинності для операції І
наступна:
a | b | a AND b |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
. 9 (основа 10) = 00000000000000000000000000001001 (основа 2) 14 (основа 10) = 00000000000000000000000000001110 (основа 2) -------------------------------- 14 & 9 (основа 10) = 00000000000000000000000000001000 (основа 2) = 8 (основа 10)
Побітове І над будь-яким числом x
та 0
дає 0
.
Виконує операцію АБО (OR) над кожною парою бітів. a
АБО b
дає 1, якщо або a
, або b
дорівнює 1
. Таблиця істинності для операції АБО
наступна:
a | b | a OR b |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
. 9 (основа 10) = 00000000000000000000000000001001 (основа 2) 14 (основа 10) = 00000000000000000000000000001110 (основа 2) -------------------------------- 14 | 9 (основа 10) = 00000000000000000000000000001111 (основа 2) = 15 (основа 10)
Побітове АБО над будь-яким числом x
та 0
дає x
.
Виконує операцію виключного АБО (XOR) над кожною парою бітів. a
викл. АБО b
дає 1, якщо a
та b
є різними. Таблиця істинності для операції XOR
наступна:
a | b | a XOR b |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
. 9 (основа 10) = 00000000000000000000000000001001 (основа 2) 14 (основа 10) = 00000000000000000000000000001110 (основа 2) -------------------------------- 14 ^ 9 (основа 10) = 00000000000000000000000000000111 (основа 2) = 7 (основа 10)
Виключне побітове АБО над будь-яким числом x
та 0
дає x.
Виконує операцію НЕ над кожним бітом. НЕ a
повертає інвертоване значення (або обернений код) операнду a
. Таблиця істинності для операції НЕ
наступна:
a | NOT a |
0 | 1 |
1 | 0 |
9 (основа 10) = 00000000000000000000000000001001 (основа 2) -------------------------------- ~9 (основа 10) = 11111111111111111111111111110110 (основа 2) = -10 (основа 10)
Побітове НЕ над будь-яким числом x
дає -(x + 1)
. Наприклад, ~-5
дорівнює 4
.
Зауважте, що через використання 32-бітного представлення чисел і ~-1
, і ~4294967295
(232-1) повернуть 0
.
Оператори бітового зсуву приймають два операнди: перший є величиною, в якій треба виконати зсув, а другий вказує кількість бітових позицій для зсуву. Напрямок операції зсуву контролюється застосованим оператором.
Оператори зсуву перетворюють свої операнди на 32-бітні цілі числа у порядку від старшого до молодшого байту та повертають результат того самого типу, до якого належить лівий операнд. Лише молодші п'ять бітів правого операнду будуть використані.
Цей оператор виконує зсув першого операнду на вказану кількість бітів ліворуч. Надлишкові біти, зсунуті ліворуч, відкидаються. Біти, додані справа, заповнюються нулями.
Наприклад, 9 << 2
дорівнює 36:
. 9 (основа 10): 00000000000000000000000000001001 (основа 2) -------------------------------- 9 << 2 (основа 10): 00000000000000000000000000100100 (основа 2) = 36 (основа 10)
Бітовий зсув будь-якого числа x
ліворуч на y
бітів дорівнює x * 2 ** y
.
Отже, для прикладу: 9 << 3
можна перекласти як: 9 * (2 ** 3) = 9 * (8) =
72
.
Цей оператор виконує зсув першого операнду на вказану кількість бітів праворуч. Надлишкові біти, зсунуті праворуч, відкидаються. Біти, додані зліва, заповнюються значенням старшого біта. Оскільки новий старший біт матиме те саме значення, що й попередній старший біт, знаковий (старший) біт не змінюється. Звідси назва "з розширенням знаку".
Наприклад, 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)
Цей оператор виконує зсув першого операнду на вказану кількість бітів праворуч. Надлишкові біти, зсунуті праворуч, відкидаються. Біти, додані зліва, заповнюються нулями. Знаковий біт отримує значення 0, а отже, результат завжди невід'ємний. На відміну від інших бітових операторів, правий зсув із заповненням нулями повертає беззнакове ціле 32-бітне число.
Для невід'ємних чисел, правий зсув із заповненням нулями та правий зсув з розширенням знаку дають однаковий результат. Наприклад, 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. Коли прапор встановлений, він має значення 1. Коли прапор очищений, він має значення 0. Припустимо, змінна flags
має двійкове значення 0101:
var flags = 5; // двійкове значення 0101
Це значення вказує:
Оскільки бітові операнди 32-бітні, 0101 насправді дорівнює 00000000000000000000000000000101, але нулями попереду можна знехтувати, оскільки вони не містять корисної інформації.
Бітова маска - це послідовність бітів, які можуть маніпулювати прапорами та/або читати їх. Зазвичай, визначається "примітивна" бітова маска для кожного прапора:
var FLAG_A = 1; // 0001 var FLAG_B = 2; // 0010 var FLAG_C = 4; // 0100 var FLAG_D = 8; // 1000
Нові бітові маски можуть створюватись застовуванням побітових логічних операторів до цих примітивних бітових масок. Наприклад, бітова маска 1011 може бути створена операцією АБО з прапорів FLAG_A, FLAG_B та FLAG_D:
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
Індивідуальні значення прапорів можна витягнути застосуванням операції І до них та бітової маски, де кожний біт, що має значення один, "витягне" відповідний прапор. Бітова маска маскує невідповідні прапори, об'єднуючи їх операцією І з нулями (звідси термін "бітова маска"). Наприклад, бітову маску 0100 можна використати, щоб побачити, чи встановлений прапор C:
// якщо ми маємо кота if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true // зробити щось }
Бітова маска з кількома встановленими прапорами діє як "або/або". Для прикладу, наступні два фрагменти еквівалентні:
// якщо ми маємо кажана або ми маємо кота // (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true if ((flags & FLAG_B) || (flags & FLAG_C)) { // зробити щось }
// якщо ми маємо кажана або кота var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110 if (flags & mask) { // 0101 & 0110 => 0100 => true // зробити щось }
Прапори можна встановити, об'єднавши їх операцією АБО з бітовою маскою, де кожний біт, що має значення один, встановить відповідний прапор, якщо прапор ще не встановлений. Наприклад, бітову маску 1100 можна використати, щоб встановити прапори C та D:
// так, ми маємо кота та качку var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100 flags |= mask; // 0101 | 1100 => 1101
Прапори можна очистити, об'єднавши їх операцією І з бітовою маскою, де кожний біт, що має значення нуль, очистить відповідний прапор, якщо він ще не очищений. Ця бітова маска може бути створена застосуванням операції НЕ до примітивних бітових масок. Наприклад, бітову маску 1010 можна використати, щоб очистити прапори A та C:
// ні, ми не маємо проблеми з мурахами або кота var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010 flags &= mask; // 1101 & 1010 => 1000
Маску також можна створити за допомогою ~FLAG_A & ~FLAG_C
(правило де Моргана):
// ні, ми не маємо проблеми з мурахами і ми не маємо кота var mask = ~FLAG_A & ~FLAG_C; flags &= mask; // 1101 & 1010 => 1000
Прапори можна перемикати, об'єднуючи їх операцією виключне АБО з бітовою маскою, де кожний біт, що має значення один, переключить відповідний прапор. Наприклад, бітову маску 0110 можна використати, щоб переключити прапори B та C:
// якщо ми не мали кажана, тепер ми його маємо, // а якщо він в нас був, бувай, кажанчику // те саме для котів var mask = FLAG_B | FLAG_C; flags = flags ^ mask; // 1100 ^ 0110 => 1010
Нарешті, усі прапори можна перевернути оператором НЕ:
// входимо у паралельний всесвіт... flags = ~flags; // ~1010 => 0101
Перетворити двійковий рядок
на десяткове число
:
var sBinString = '1011'; var nMyNumber = parseInt(sBinString, 2); alert(nMyNumber); // виводить 11, тобто 1011
Перетворити десяткове число
на двійковий рядок
:
var nMyNumber = 11; var sBinString = nMyNumber.toString(2); alert(sBinString); // виводить 1011, тобто 11
Ви можете створювати маски з набору булевих
значень наступним чином:
function createMask() { var nMask = 0, nFlag = 0, nLen = arguments.length > 32 ? 32 : arguments.length; for (nFlag; nFlag < nLen; nMask |= arguments[nFlag] << nFlag++); return nMask; } var mask1 = createMask(true, true, false, true); // 11, тобто: 1011 var mask2 = createMask(false, false, true); // 4, тобто: 0100 var mask3 = createMask(true); // 1, тобто: 0001 // і т.д. alert(mask1); // виводить 11, тобто: 1011
Якщо ви бажаєте створити масив
булевих значень
з маски, можете скористатись цим кодом:
function arrayFromMask(nMask) { // Значенння nMask має бути між -2147483648 та 2147483647 if (nMask > 0x7fffffff || nMask < -0x80000000) { throw new TypeError('arrayFromMask - out of range'); } for (var nShifted = nMask, aFromMask = []; nShifted; aFromMask.push(Boolean(nShifted & 1)), nShifted >>>= 1); return aFromMask; } var array1 = arrayFromMask(11); var array2 = arrayFromMask(4); var array3 = arrayFromMask(1); alert('[' + array1.join(', ') + ']'); // виводить "[true, true, false, true]", тобто: 11, тобто: 1011
Ви можете перевірити обидва алгоритми одночасно…
var nTest = 19; // наша користувацька маска var nResult = createMask.apply(this, arrayFromMask(nTest)); alert(nResult); // 19
Суто з навчальною метою (оскільки існує метод Number.toString(2)
) ми показуємо, як можна модифікувати алгоритм arrayFromMask
для створення рядка
, що містить двійкове представлення числа
, а не масиву
булевих значень
:
function createBinaryString(nMask) { // Значення nMask має бути між -2147483648 та 2147483647 for (var nFlag = 0, nShifted = nMask, sMask = ''; nFlag < 32; nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1); return sMask; } var string1 = createBinaryString(11); var string2 = createBinaryString(4); var string3 = createBinaryString(1); alert(string1); // виводить 00000000000000000000000000001011, тобто 11
Специфікація | Статус | Коментар |
---|---|---|
{{SpecName('ES1')}} | {{Spec2('ES1')}} | Початкове визначення. |
{{SpecName('ES5.1', '#sec-11.7')}} | {{Spec2('ES5.1')}} | Визначені у кількох розділах специфікації: Побітовий оператор НЕ, Бітові оператори зсуву, Двійкові побітові оператори |
{{SpecName('ES6', '#sec-bitwise-shift-operators')}} | {{Spec2('ES6')}} | Визначені у кількох розділах специфікації: Побітовий оператор НЕ, Бітові оператори зсуву, Двійкові побітові оператори |
{{SpecName('ESDraft', '#sec-bitwise-shift-operators')}} | {{Spec2('ESDraft')}} | Визначені у кількох розділах специфікації: Побітовий оператор НЕ, Бітові оператори зсуву, Двійкові побітові оператори |
The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.
{{Compat("javascript.operators.bitwise")}}