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

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

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

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

9 ответов


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

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

 Read: 00000001
Write: 00000010

так что если вы хотите пройти читать И напишите, вы бы прошли (чтение / запись), который затем объединяет эти два в

00000011

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

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

проверки

00000011 &
00000001

возвращает

00000001

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

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

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

я просто XOR текущее значение с (слева / справа), который будет поворачивать влево и вправо, в этом случае.

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

x << y

это то же самое, что

x * 2y

если вам нужно быстро умножить на два, но следить за смещением 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

цвета часто хранятся таким образом (с наиболее значительным байтом либо игнорируется или используется в качестве Альфа):

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)

побитовые операторы-это операторы, которые работают над битом за раз.

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

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

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

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

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

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

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

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 отдельные операции " и " параллельно, по одной для каждого столбца.

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


это побитовые операторы, все поддерживаемые в JavaScript:

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

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

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

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

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

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

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


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

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

надеюсь, что это помогает.


когда упоминается термин "побитовый", иногда уточняется, что is не является" логическим " оператором.

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

возьмите expr1 & & expr2, например.

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

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

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

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

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

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

  • побитовое и

  • побитовое или

  • побитовое Не

  • побитовое XOR

  • etc

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

    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 * 2y соответственно.

например.

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 statment

например.

int min(int x, int y)
{
    return y ^ ((x ^ y) & - (x < y))
}
  • Decimal в двоичный преобразование

например.

#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 популярный метод, becouse своих complixblity и пользы reare программником.
    • побитовый оператор XOR является наиболее полезным оператор с точки зрения технического интервью.

bitwuse shifting работает только с номером + ve

также широкий диапазон пользы побитовой логики


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

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

         5: 00000101
         3: 00000011

оба одно: 00000001 0-ложь, 1-истина

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


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

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