Что делает битовое смещение (влево или вправо) и для чего оно используется? - PullRequest
63 голосов
/ 17 июня 2011

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

РЕДАКТИРОВАТЬ

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

Ответы [ 9 ]

47 голосов
/ 17 июня 2011

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

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

1111 1110 << 2 
1111 1000 

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

0001 1111 >> 3 
0000 0011 

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

1100 1100 >> 1
1110 0110 

и он сохраняется в течение нескольких смен:

1100 1100 >> 2
1111 0011

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

1100 1100 >>> 1
0110 0110 

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

Математически, сдвиг влево - это * = 2, 2 сдвига влево - это * = 4 и так далее.Сдвиг вправо - это / = 2 и т. Д.

35 голосов
/ 17 июня 2011

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

24 голосов
/ 29 июля 2015

Сдвиг влево

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

14 голосов
/ 04 апреля 2016

Сдвиг влево : Он равен произведению значения, которое должно быть сдвинуто, и 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
3 голосов
/ 05 апреля 2017

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

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

В C / C ++ это можно записать как

#include <math.h>

x = x * pow(2, 5);
y = y / pow(2, 5);
3 голосов
/ 22 июля 2015

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

2 голосов
/ 21 января 2015

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

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

2 голосов
/ 17 июня 2011

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

  • Битовые операции, например, преобразование в и из base64 (что составляет 6 бит вместо 8)
  • делает мощность 2 операций (1 << 4 равно 2^4 т.е. 16)
  • Написание более читабельного кода при работе с битами. Например, определение констант с помощью 1 << 4 или 1 << 5 более читабельно.
0 голосов
/ 07 октября 2014

Вот пример:

#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();
}
...