Что делает побитовый сдвиг (влево или вправо) и для чего он используется?

Я видел операторы >> и << в различном коде, на который я смотрел (ничто из того, что я на самом деле не понял), но мне просто интересно, что они на самом деле делают и какие практические применения они есть.

ИЗМЕНИТЬ

Если сдвиги похожи на x * 2 и x / 2, какова реальная разница от фактического использования операторов * и /? Есть ли разница в производительности?

+52
17 июн. '11 в 12:35
источник поделиться
9 ответов

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

У вас есть набор бит, и вы перемещаете некоторые из них за пределы:

1111 1110 << 2 
1111 1000 

он заполняется справа со свежими нулями.:)

0001 1111 >> 3 
0000 0011 

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

1100 1100 >> 1
1110 0110 

и он сохраняется при нескольких сдвигах:

1100 1100 >> 2
1111 0011

Если вы не хотите, чтобы первый бит сохранялся, вы используете (в Java, Scala, С++, C afaik и, возможно, больше) оператор с тройным знаком:

1100 1100 >>> 1
0110 0110 

В другом направлении нет эквивалента, потому что это не имеет смысла - может быть, в вашем особом контексте, но не в общем.

Математически сдвиг влево - это * = 2, 2 левых сдвига - это * = 4 и т.д. Правый сдвиг равен /= 2 и т.д.

+39
17 июн. '11 в 12:42
источник

Сдвиг левого бита для умножения на любую мощность двух и правого смещения бит для разделения на любую мощность в два. Например, x = x * 2; также может быть записано как x<<1 или x = x*8 может быть записано как x<<3 (поскольку 2 до степени 3 равно 8). Аналогично x = x / 2; есть x>>1 и т.д.

+28
17 июн. '11 в 12:39
источник

Левый сдвиг

x = x * 2^value (нормальная работа)

x << value (побитовая операция)


x = x * 16 (что совпадает с 2^4)

эквивалент левого сдвига будет x = x << 4

Сдвиг вправо

x = x / 2^value (нормальная арифметическая операция)

x >> value (побитовая операция)


x = x / 8 (что совпадает с 2^3)

Эквивалент правого сдвига будет x = x >> 3

+17
29 июл. '15 в 10:28
источник

Сдвиг влево: он равен произведению значения, которое должно быть сдвинуто, а 2 увеличено до значения количества битов, которые нужно сдвинуть.

Пример:

1<<3
0000 0001  ---> 1
Shift by 1 bit
0000 0010 ----> 2 which is equal to 1*2^1
Shift By 2 bits
0000 0100 ----> 4 which is equal to 1*2^2
Shift by 3 bits
0000 1000 ----> 8 which is equal to 1*2^3

Сдвиг вправо: он равен частному значению, которое должно быть сдвинуто на 2, поднятое до степени смещения числа бит.

Пример:

8>>3
0000 1000  ---> 8 which is equal to 8/2^0
Shift by 1 bit
0000 0100 ----> 4 which is equal to 8/2^1
Shift By 2 bits
0000 0010 ----> 2 which is equal to 8/2^2
Shift by 3 bits
0000 0001 ----> 1 which is equal to 8/2^3
+10
04 апр. '16 в 0:30
источник

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

+3
22 июл. '15 в 8:43
источник

Некоторые примеры:

  • Бит-операции, например, преобразование в и из base64 (которое составляет 6 бит вместо 8)
  • выполнение 2-х операций (1 << 4 равно 2^4, т.е. 16)
  • Написание более читаемого кода при работе с битами. Например, определяя константы, используя 1 << 4 или 1 << 5 является более читаемым.
+2
17 июн. '11 в 12:37
источник

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

Например, вычисление мощности 2 ^ n: -

int value = 1;
while (exponent<n)
    {
       //print out current power of 2
        value =value *2; // equivalent machine level left shift bit wise operation
        exponent++;
         }
    }

Аналогичный код с побитовым левым сдвигом будет выглядеть так:

value = 1 << n;

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

+1
21 янв. '15 в 19:09
источник

Перемещение левого бита для умножения на любую мощность в два. Смещение правого бита для деления на любую мощность в два раза.

x = x << 5; // Left shift
y = y >> 5; // Right shift

В C/С++ он может быть записан как,

#include <math.h>

x = x * pow(2, 5);
y = y / pow(2, 5);
+1
05 апр. '17 в 16:30
источник

Вот пример:

#include"stdio.h"
#include"conio.h"

void main()
{
    int rm,vivek;
    clrscr();
    printf("enter the any numbers\t(e.g)1,2,5");
    scanf("%d",&rm);//rm=5(0101)<<2(two step add zero's)so,value is 10100
    printf("this lift shitf value%d=%d",rm,rm<<4);
    printf("this right shitf value%d=%d",rm,rm>>2);
    getch();
}
0
07 окт. '14 в 7:56
источник

Посмотрите другие вопросы по меткам или Задайте вопрос