Javascript.RU

Побитовые операторы

Описание, примеры

Побитовые операторы интерпретируют операнды как последовательность из 32 битов (нулей и единиц). Они производят операции, используя двоичное представление числа и возвращают новую последовательность из 32 бит (число) в качестве результата.

В следующей таблице перечислены все побитовые операторы.
Далее двоичное представление числа и операторы разобраны более подробно.

Оператор Использование Описание
Побитовое И (AND) a & b Ставит 1 на каждого бита результата, для которого соответствующие биты операндов равны 1.
Побитовое ИЛИ (OR) a | b Ставит 1 для каждого бита результата, для которого хотя бы один из соответствующих битов операндов равен 1.
Побитовое исключающее ИЛИ (XOR) a ^ b Ставит 1 для каждого бита результата, для которого только один(но не оба) из соответствующих битов операндов равен 1.
Побитовое НЕ (NOT) ~ a Заменяет каждый бит операнда на противоположный.
Левый сдвиг a << b Сдвигает двоичное представление a на b битов влево, добавляя справа нули.
Правый сдвиг, переносящий знак a >> b Сдвигает двоичное представление a на b битов вправо, отбрасывая сдвигаемые биты.
Правый сдвиг с заполнением нулями a >>> b Сдвигает двоичное представление a на b битов вправо, отбрасывая сдвигаемые биты и добавляя нули слева.

Формат 32-битного целого числа со знаком

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

"Старший бит слева" - означает, что самый значимый бит (битовая позиция с самым большим значением) находится на крайнем левом месте.

"Дополнение до двойки" означает, что двоичный вид числа, обратного данному (например, 5 и -5) получается путем обращения(двоичного НЕ) всех битов с добавлением 1.

Например, вот число 314:

00000000000000000000000100111010

Чтобы получить -314, первый шаг - обратить биты числа:

11111111111111111111111011000101

Второй шаг - прибавить единицу:

11111111111111111111111011000110

Принцип дополнения до двойки делит все двоичные представления на два множества: если крайний-левый бит равен 0 - число положительное, если 1 - число отрицательное. Поэтому этот бит называется знаковым битом.

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

Бинарные побитовые операторы работают следующим образом:

  • Операнды преобразуются в 32-битные целые числа, представленные последовательностью битов (нулей и единиц)
  • Каждый бит в первом операнде рассматривается вместе с соответствующим битом второго операнда: первый бит с первым, второй со вторым и т.п.
  • Оператор применяется к каждой паре бит, давая соответствующий бит результата.

& (побитовое И)

Выполняет операцию И над каждой парой бит. a И b равно единице только когда оба бита равны единице.

Таблица истинности для И:

a b a И 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)

| (Побитовое ИЛИ)

Выполняет операцию ИЛИ над каждой парой бит. a ИЛИ b равно 1, если хотя бы один бит из a,b равен 1.

Таблица истинности для ИЛИ:

a b a ИЛИ 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)

^ (Исключающее ИЛИ)

Выполняет операцию исключающего ИЛИ над каждой парой бит.
a Исключающее ИЛИ b равно 1, если только a=1 или только b=1, но не оба одновременно a=b=1.

Таблица истинности для исключающего ИЛИ:

a b a Исключающее ИЛИ 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)

~ (Побитовое НЕ)

Производит операцию НЕ над каждым битом, заменяя его на обратный ему.

Таблица истинности для НЕ:

a НЕ a
0 1
1 0
9 (по осн. 10) 
  = 00000000000000000000000000001001 (по осн. 2)
               --------------------------------
~9 (по осн. 10) 
  = 11111111111111111111111111110110 (по осн. 2) 
  = -10 (по осн. 10)

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

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

Направление сдвига - то же, что и направление стрелок в операторе.

<< (Левый сдвиг)

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

Например, 9 << 2 даст 36:

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

>> (Правый сдвиг, переносящий знак)

Этот оператор сдвигает биты вправо, отбрасывая лишние. Копии крайнего-левого бита добавляются слева. Так как итоговый крайний-левый бит имеет то же значение, что и исходный, знак числа (представленный крайним-левым битом) не изменяется.

Поэтому он назван "переносящим знак".

Например, 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, поэтому результат всегда положителен.
Для неотрицательных чисел правый сдвиг с заполнением нулями и правый сдвиг с переносом знака дадут одинаковый результат, т.к в обоих случаях слева добавятся нули.

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

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

См. также


Автор: Гость (не зарегистрирован), дата: 7 июня, 2011 - 10:41
#permalink

^ всё таки работает, как логическое XOR, а не как побитовое. WebKit, FireFox.


Автор: Гость Андрюха (не зарегистрирован), дата: 23 августа, 2011 - 06:00
#permalink

зачем вообще нужны побитовые операторы в JavaScript? хотелось бы узнать об их практическом применении


Автор: akimoto (не зарегистрирован), дата: 24 августа, 2011 - 17:07
#permalink

как-бы вот для чего, например:
function toInt(number) {
return number && + number | 0 || 0;
}
функция приводит к int, либо возвращает 0, если это нельзя сделать


Автор: remember_me! (не зарегистрирован), дата: 22 октября, 2020 - 08:31
#permalink

Гореть тебе в аду ублюдок!
Удобно ему блять


Автор: Гость (не зарегистрирован), дата: 9 августа, 2013 - 10:23
#permalink

Пишу игрушку на html5 canvas (а для чего еще canvas если не для этого?! и чем управлять логикой canvas, если не JS?! :-) ). Так вот к давнему вопросу одного из предыдущих комментаторов - слава разработчикам, включившим побитовые операции в javascript!


Автор: Гость (не зарегистрирован), дата: 28 декабря, 2013 - 16:11
#permalink

Зачем web-дизайнерам битовые операции если они кроме сайтов ничего не паяют. Я понимаю реализовывать алгоритм RSA или MD5 на С/С++ с применением SIMD.


Автор: Гость (не зарегистрирован), дата: 6 января, 2014 - 11:34
#permalink

web-дизайнер и программист - совсем разные понятия.


Автор: Гость (не зарегистрирован), дата: 23 января, 2014 - 00:39
#permalink

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

Сейчас js может многое с появлением и канваса, и вебгл, и ArrayBuffer (это дало возможность хоть архивы создавать в браузере или загружать с сервера и тут же их распаковывать (3д сцена в формате коллада весит несколько метров, а в архиве килобайты, так что грузить с сервера проще архив, а затем js-ом распаковать и обрабатывать), хоть напищи компилятор и компилируй исходники на си в ехе... делай все, на что фантазии хватит)

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


Автор: Vady (не зарегистрирован), дата: 12 января, 2014 - 15:17
#permalink

можно сделать аналог округления в меньшую сторону (floor):
alert(~~100/3)


Автор: Гость (не зарегистрирован), дата: 3 июня, 2014 - 10:36
#permalink

alert((100/3)|0);
вдвое шустрее Math.floor


Автор: :-( (не зарегистрирован), дата: 18 февраля, 2015 - 03:33
#permalink

Не понял чем недоволен комментатор от 27 декабря, 2013 - 18:25 ?


Автор: Гость (не зарегистрирован), дата: 25 февраля, 2015 - 18:56
#permalink

To 18 февраля, 2015 - 04:33

Читабельность кода падает в разы.


Автор: Гость (не зарегистрирован), дата: 6 мая, 2015 - 16:16
#permalink

в чем проблема

// шустрое округление в меньшую сторону
var x = (100/3)|0;

скорость растет, а "читабельность кода" не падает


Автор: Гость (не зарегистрирован), дата: 20 февраля, 2021 - 21:47
#permalink

Объясните как это работает, или где можно посмотреть объяснение.

Почему побитовый оператор ИЛИ(OR) "убирает" дробную часть числа?


Автор: Zenitchik, дата: 14 мая, 2015 - 22:03
#permalink

Когда над проектом работает команда - используются те приёмы, которые ясны каждому в команде. А остальным - незачем.

Проблемы с читаемостью кода возникают в основном у тех, кто недавно перешёл из других языков и не успел привыкнуть к типовым приёмам.


Автор: Гость (не зарегистрирован), дата: 19 мая, 2016 - 14:44
#permalink

Подскажите люди добрые! Есть слово в в (hex) счислении , которое мы должны преобразовать в (bin) , потом из этого слова мы хотим ВЫВЕСТИ каждый бит


Автор: Гость (не зарегистрирован), дата: 14 июля, 2017 - 16:40
#permalink

Есть слово в в (hex) счислении , которое мы должны преобразовать в (bin) , потом из этого слова мы хотим ВЫВЕСТИ каждый бит

Серьёзно? Ну например так:

var strHex = "123ABC", 
    n = parseInt(strHex) || 0,
    bits = n.toString(2).split("");
console.log(bits.join(" "));

Неоптимально, зато понятно и читабельно. А то тут выше дизайнеры испугались "плохой читаемости"


Автор: Гость (не зарегистрирован), дата: 25 февраля, 2018 - 11:26
#permalink

Доработанный вариант
var strHex = "123ABC", n=parseInt(strHex,16), bits=n.toString(2); console.log(bits);


Автор: Гость (не зарегистрирован), дата: 24 апреля, 2019 - 17:12
#permalink

Статья класс, пойду подрочу


Автор: Гость (не зарегистрирован), дата: 24 апреля, 2019 - 17:14
#permalink

И я


Автор: Гость (не зарегистрирован), дата: 24 апреля, 2019 - 17:14
#permalink

Ну и я тоже


Автор: Гость (не зарегистрирован), дата: 12 апреля, 2022 - 15:23
#permalink

Автор: Гость (не зарегистрирован), дата: 16 апреля, 2022 - 00:21
#permalink

Автор: Гость (не зарегистрирован), дата: 16 апреля, 2022 - 13:26
#permalink

Автор: Гость (не зарегистрирован), дата: 30 августа, 2022 - 22:58
#permalink

Мохнатый писюн не стыдно?


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
2 + 6 =
Введите результат. Например, для 1+3, введите 4.
 
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum