Как работают операторы сдвига в Java?

Я пытаюсь понять операторов смены и не могу получить много. Когда я попытался выполнить приведенный ниже код

System.out.println(Integer.toBinaryString(2 << 11));
System.out.println(Integer.toBinaryString(2 << 22));
System.out.println(Integer.toBinaryString(2 << 33));
System.out.println(Integer.toBinaryString(2 << 44));
System.out.println(Integer.toBinaryString(2 << 55));

Я получаю ниже

1000000000000    
100000000000000000000000    
100    
10000000000000    
1000000000000000000000000    

Может кто-нибудь объяснить, пожалуйста?

9 ответов

Решение
System.out.println(Integer.toBinaryString(2 << 11)); 

Сдвиги двоичные 2 (10) в 11 раз влево. Следовательно: 1000000000000

System.out.println(Integer.toBinaryString(2 << 22)); 

Сдвиги двоичные 2 (10) в 22 раза влево. Отсюда: 100000000000000000000000

System.out.println(Integer.toBinaryString(2 << 33)); 

Теперь int имеет 4 байта, следовательно, 32 бита. Поэтому, когда вы делаете сдвиг на 33, это эквивалентно сдвигу на 1. Следовательно: 100

2 из десятичной системы счисления в двоичном виде выглядит следующим образом

10

сейчас, если вы делаете

2 << 11

было бы, 11 нулей будет дополнен на правой стороне

1000000000000

Оператор сдвига влево со знаком "<<" сдвигает битовую комбинацию влево, а оператор сдвига влево со знаком ">>" сдвигает битовую комбинацию вправо. Битовая комбинация задается левым операндом, а число позиций для смещения - правым операндом. Оператор сдвига вправо без знака ">>>" сдвигает ноль в крайнее левое положение, а крайнее левое положение после ">>" зависит от расширения знака [..]

сдвиг влево приводит к умножению на 2 (*2) в терминах или арифметике


Например

2 в двоичном 10если вы делаете <<1 это было бы 100 который 4

4 в двоичном 100если вы делаете <<1 это было бы 1000 который 8


Также см

Сдвиг вправо и влево работает одинаково, вот как работает сдвиг вправо; Сдвиг вправо: Оператор сдвига вправо, >>, сдвигает все биты в значении вправо на указанное число раз. Его общая форма:

value >> num

Здесь num указывает количество позиций для сдвига вправо значения в значении. То есть >> перемещает все биты в указанном значении вправо на количество битовых позиций, указанных в num. Следующий фрагмент кода сдвигает значение 32 вправо на две позиции, в результате чего устанавливается значение 8:

int a = 32;
a = a >> 2; // a now contains 8

Когда значение имеет биты, которые "сдвинуты", эти биты теряются. Например, следующий фрагмент кода сдвигает значение 35 вправо на две позиции, что приводит к потере двух младших битов, в результате чего снова устанавливается значение 8.

int a = 35;
a = a >> 2; // a still contains 8

Глядя на ту же операцию в двоичном коде, более четко видно, как это происходит:

00100011 35 >> 2
00001000 8

Каждый раз, когда вы сдвигаете значение вправо, оно делит это значение на два и отбрасывает любой остаток. Вы можете воспользоваться этим для высокопроизводительного целочисленного деления на 2. Конечно, вы должны быть уверены, что не сдвигаете биты с правого конца. Когда вы сдвигаетесь вправо, верхние (самые левые) биты, выставленные правым сдвигом, заполняются предыдущим содержимым верхнего бита. Это называется расширением знака и служит для сохранения знака отрицательных чисел при их правильном смещении. Например, –8 >> 1 является –4в двоичном виде

11111000 –8 >>1
11111100 –4

Интересно отметить, что если вы сдвинете вправо –1, результат всегда останется –1, поскольку расширение знака продолжает вводить больше единиц в старших разрядах. Иногда нежелательно подписывать значения-расширения, когда вы сдвигаете их вправо. Например, следующая программа преобразует значение байта в его шестнадцатеричное строковое представление. Обратите внимание, что смещенное значение маскируется с помощью AND с 0x0f для отбрасывания любых битов с расширенными знаками, чтобы это значение можно было использовать в качестве индекса в массиве шестнадцатеричных символов.

// Masking sign extension.
class HexByte {
  static public void main(String args[]) {
    char hex[] = {
      '0', '1', '2', '3', '4', '5', '6', '7',
      '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
    };
  byte b = (byte) 0xf1;
 System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);
}
}

Вот результат этой программы:

b = 0xf1

Я считаю, что это может помочь:

    System.out.println(Integer.toBinaryString(2 << 0));
    System.out.println(Integer.toBinaryString(2 << 1));
    System.out.println(Integer.toBinaryString(2 << 2));
    System.out.println(Integer.toBinaryString(2 << 3));
    System.out.println(Integer.toBinaryString(2 << 4));
    System.out.println(Integer.toBinaryString(2 << 5));

Результат

    10
    100
    1000
    10000
    100000
    1000000

Отредактировано:

Обязательно прочитайте (как работают операторы сдвига)

Я думаю, что это будет следующим, например:

  • Подпись слева сдвиг

[ 2 << 1 ] is => [10 (двоичный из 2) добавить 1 ноль в конце двоичной строки] Следовательно, 10 будет 100, что станет 4.

Сдвиг влево со знаком использует умножение... Так что это также можно рассчитать как 2 * (2^1) = 4. Другой пример [2 << 11] = 2 * (2 ^ 11) = 4096

  • Подпись вправо сдвиг

[4 >> 1] is => [100 (двоичный из 4) удалить 1 ноль в конце двоичной строки] Следовательно, 100 будет 10, что становится 2.

Сдвиг вправо со знаком использует деление... Так что это также можно рассчитать как 4 / (2^1) = 2 Другой пример [4096 >> 11] = 4096 / (2 ^ 11) = 2

Это сдвинет биты, заполнив так много 0's,

Например,

  • двоичный 10 который является цифрой 2 сдвиг влево на 2 1000 который является цифрой 8
  • двоичный 10 который является цифрой 2 сдвиг влево на 3 10000 который является цифрой 16

Сдвиг влево, логически простой, если 1<<11 будет стремиться к 2048, а 2<<11 даст 4096

В Java-программировании int a = 2 << 11;

// it will result in 4096

2<<11 = 2*(2^11) = 4096

Сдвиг может быть реализован с типами данных (char, int и long int). Данные с плавающей запятой и двойные данные не могут быть сдвинуты.

value= value >> steps  // Right shift, signed data.
value= value << steps  // Left shift, signed data.

Типичное использование сдвига переменной и ее присвоения может быть переписано с помощью сокращенных операторов << =, >> = или >>> =, также известных в спецификации как операторы сложного присваивания.

Например,

i >>= 2

дает тот же результат, что и

i = i >> 2
Другие вопросы по тегам