Что такое побитовые операторы?

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

Я читал статью о JavaScript, которая, по-видимому, поддерживает побитовые операции. Я продолжаю видеть эту операцию, упомянутую в местах, и я пробовал прочитывать, чтобы понять, что это такое, но я просто не понимаю. Так что это? Яркие примеры были бы замечательными!: D

Еще несколько вопросов - каковы практические применения побитовых операций? Когда вы можете использовать их?

Ответы

Ответ 1

Поскольку никто не затронул тему, почему они полезны:

Я использую побитовые операции во время работы с флагами. Например, если вы хотите передать серию флагов в операцию (скажем, File.Open, с включенным режимом чтения и режимом записи), вы можете передать их как одно значение. Это достигается путем присвоения каждому возможному флагу своего собственного бита в битете (байте, коротком, int или длинном). Например:

 Read: 00000001
Write: 00000010

Итак, если вы хотите передать read и write, вы передадите (READ | WRITE), который затем объединяет два в

00000011

Которая затем может быть расшифрована на другом конце, например:

if ((flag & Read) != 0) { //...

который проверяет

00000011 &
00000001

который возвращает

00000001

который не равен 0, поэтому флаг указывает READ.

Вы можете использовать XOR для переключения различных битов. Я использовал это при использовании флага для указания направленных входов (вверх, вниз, влево, вправо). Например, если спрайт движется горизонтально, и я хочу, чтобы он развернулся:

     Up: 00000001
   Down: 00000010
   Left: 00000100
  Right: 00001000
Current: 00000100

Я просто XOR текущее значение с помощью (LEFT | RIGHT), который в этом случае отключит LEFT и RIGHT.

Сдвиг бит полезен в нескольких случаях.

x << y

совпадает с

x * 2 y

если вам нужно быстро умножить на мощность в два, но следите за переходом 1-битного в верхний бит - это делает число отрицательным, если оно не указано. Это также полезно при работе с различными размерами данных. Например, чтение целого из четырех байтов:

int val = (A << 24) | (B << 16) | (C << 8) | D;

Предполагая, что A является наиболее значимым байтом, а D - наименьшим. Это закончилось бы так:

A = 01000000
B = 00000101
C = 00101011
D = 11100011
val = 01000000 00000101 00101011 11100011

Цвета часто сохраняются таким образом (с самым значительным байтом, который игнорируется или используется как Alpha):

A = 255 = 11111111
R = 21 = 00010101
G = 255 = 11111111
B = 0 = 00000000
Color = 11111111 00010101 11111111 00000000

Чтобы снова найти значения, просто сдвиньте биты вправо до тех пор, пока они внизу, а затем не отбросьте оставшиеся разряды более высокого порядка:

Int Alpha = Color >> 24
Int Red = Color >> 16 & 0xFF
Int Green = Color >> 8 & 0xFF
Int Blue = Color & 0xFF

0xFF - это то же самое, что и 11111111. Таким образом, для Red, вы бы это сделали:

Color >> 16 = (filled in 00000000 00000000)11111111 00010101  (removed 11111111 00000000)
00000000 00000000 11111111 00010101 &
00000000 00000000 00000000 11111111 =
00000000 00000000 00000000 00010101 (The original value)

Ответ 2

Побитовые операторы - это операторы, которые работают по меньшей мере за раз.

И есть 1, только если оба его входа равны 1.

ИЛИ равно 1, если один или несколько его входов равны 1.

XOR равно 1, только если один из его входов равен 1.

NOT равно 1, только если его ввод равен 0.

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

AND|0 1      OR|0 1
---+----    ---+----
  0|0 0       0|0 1
  1|0 1       1|1 1

XOR|0 1     NOT|0 1
---+----    ---+---
  0|0 1        |1 0
  1|1 0

Например, если вам нужны только младшие 4 бита целого числа, вы И его с 15 (двоичный код 1111), поэтому:

    203: 1100 1011
AND  15: 0000 1111
------------------
 IS  11: 0000 1011

Ответ 3

Стоит отметить, что однобитовые таблицы истинности, перечисленные как другие ответы, работают только по одному или двум входным битам за раз. Что происходит, когда вы используете целые числа, например:

int x = 5 & 6;

Ответ лежит в двоичном разложении каждого входа:

  5 = 0 0 0 0 0 1 0 1
& 6 = 0 0 0 0 0 1 1 0
---------------------
      0 0 0 0 0 1 0 0

Каждая пара бит в каждом столбце запускается через функцию "И", чтобы дать соответствующий выходной бит в нижней строке. Таким образом, ответ на вышеупомянутое выражение - 4. ЦП выполнил (в этом примере) 8 отдельных операций "И" параллельно, по одному для каждого столбца.

Я упоминаю об этом, потому что я все еще помню, что это "AHA!" момент, когда я узнал об этом много лет назад.

Ответ 4

Это побитовые операторы, все они поддерживаются в JavaScript:

  • op1 & op2 - оператор AND сравнивает два бита и генерирует результат 1, если оба бита равны 1; в противном случае возвращается 0.

  • op1 | op2 op1 | op2 - оператор OR сравнивает два бита и генерирует результат 1, если биты дополняют друг друга; в противном случае возвращается 0.

  • op1 ^ op2 - Оператор EXCLUSIVE-OR сравнивает два бита и возвращает 1, если один из битов op1 ^ op2 1, и дает 0, если оба бита равны 0 или 1.

  • ~op1 - The COMPLEMENT оператор используется, чтобы инвертировать все биты операнда.

  • op1 << op2 - оператор SHIFT LEFT перемещает биты влево, отбрасывает крайний левый бит и присваивает крайнему правому биту значение 0. Каждое перемещение влево эффективно умножает op1 на 2.

  • op1 >> op2 - оператор SHIFT RIGHT перемещает биты вправо, отбрасывает крайний правый бит и присваивает крайнему левому биту значение 0. Каждое перемещение вправо эффективно делит op1 пополам. Крайний левый бит знака сохраняется.

  • op1 >>> op2 - оператор SHIFT RIGHT - ZERO FILL перемещает биты вправо, отбрасывает крайний правый бит и присваивает крайнему левому биту значение 0. Каждое перемещение вправо эффективно делит op1 пополам. Самый левый бит знака сбрасывается.

Ответ 5

Чтобы разбить его немного больше, он имеет много общего с двоичным представлением рассматриваемого значения.

For example (in decimal):
x = 8
y = 1

would come out to (in binary):
x = 1000
y = 0001

From there, you can do computational operations such as 'and' or 'or'; in this case:
x | y = 
1000 
0001 |
------
1001

or...9 in decimal

Надеюсь, это поможет.

Ответ 6

Когда упоминается термин "поразрядный", иногда уточняется, что это не "логический" оператор.

Например, в JavaScript побитовые операторы обрабатывают свои операнды как последовательность из 32 бит (нули и единицы); Между тем логические операторы обычно используются с логическими значениями , но могут работать с небулевыми типами.

Возьмем expr1 && Например, expr2.

Возвращает expr1, если он может быть преобразован к ложному; в противном случае возвращает expr2. Таким образом, при использовании с булевыми значениями, & & возвращает true, если оба операнда правда; в противном случае возвращает false.

a = "Cat" && "Dog"     // t && t returns Dog
a = 2 && 4     // t && t returns 4

Как отмечали другие, 2 и 4 побитовое И, поэтому оно вернет 0.

Вы можете скопировать следующее в test.html или что-то еще и протестировать:

<html>
<body>
<script>
    alert("\"Cat\" && \"Dog\" = " + ("Cat" && "Dog") + "\n"
        + "2 && 4 = " + (2 && 4) + "\n"
        + "2 & 4 = " + (2 & 4));
</script>

Ответ 7

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

операции:

  • побитовое И

  • побитовое ИЛИ

  • поразрядно НЕ

  • побитовый XOR

  • так далее

Элемент списка

    AND|0 1        OR|0 1 
    ---+----      ---+---- 
      0|0 0         0|0 1 
      1|0 1         1|1 1 

   XOR|0 1        NOT|0 1 
   ---+----       ---+--- 
     0|0 1           |1 0 
     1|1 0

Например.

    203: 1100 1011
AND  15: 0000 1111
------------------
  =  11: 0000 1011

Использование побитового оператора

  • Операторы левого и правого сдвига эквивалентны умножению и делению на x * 2 y соответственно.

Например.

int main()
{
     int x = 19;
     printf ("x << 1 = %d\n" , x <<1);
     printf ("x >> 1 = %d\n", x >>1);
     return 0;
}
// Output: 38 9
  • Оператор & может быть использован для быстрой проверки, является ли число нечетным или четным

Например.

int main()
{
    int x = 19;
    (x & 1)? printf("Odd"): printf("Even");
    return 0;
 }
// Output: Odd
  • Быстрый поиск минимумов x и y без указания if else

Например.

int min(int x, int y)
{
    return y ^ ((x ^ y) & - (x < y))
}
  • Десятичное в двоичное преобразование

Например.

#include <stdio.h>
int main ()
{
    int n , c , k ;
    printf("Enter an integer in decimal number system\n " ) ;
    scanf( "%d" , & n );
    printf("%d in binary number
    system is: \n " , n ) ;
    for ( c = 31; c >= 0 ; c -- )
    {
         k = n >> c ;
         if ( k & 1 )
              printf("1" ) ;
         else
              printf("0" ) ;
      }
      printf(" \n " );
      return 0 ;
}
  • Шифрование с помощью шлюза XOR является популярной техникой, потому что оно универсально и широко используется программистом.
    • побитовый оператор XOR является наиболее полезным оператором с точки зрения технического интервью.

битовое смещение работает только с номером +ve

Также существует широкий спектр использования побитовой логики

Ответ 8

Это может помочь подумать об этом таким образом. Вот как работает AND (&):

В основном говорят, что оба эти числа одни, поэтому, если у вас есть два номера 5 и 3, они будут преобразованы в двоичные файлы, и компьютер будет думать

         5: 00000101
         3: 00000011

оба: 00000001 0 - false, 1 истинно

Таким образом, AND из 5 и 3 является одним. Оператор OR (|) делает то же самое, за исключением того, что только одно из чисел должно быть одно для вывода 1, а не для обоих.

Ответ 9

См. страницу Wikipedia Побитовая операция с примерами

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

Ответ 10

Я слышал о том, насколько медленными были побитовые операторы JavaScript. Я сделал несколько тестов для моего последнего сообщения в блоге и выяснил, что они были на 40-80% быстрее, чем арифметическая альтернатива в нескольких тестах. Возможно, они были медленными. В современных браузерах я их люблю.

У меня есть один случай в моем коде, который будет быстрее и легче читать из-за этого. Я буду держать глаза открытыми для большего.