Подтвердить что ты не робот

Понять оператора сдвига

Я не могу понять этот оператор сдвига (ссылка С#):

class MainClass1
{
 static void Main()
    {
        int i = 1;
        long lg = 1;
        Console.WriteLine("0x{0:x}", i << 1);
        Console.WriteLine("0x{0:x}", i << 33);
        Console.WriteLine("0x{0:x}", lg << 33);
    }
}

/*
Output:
0x2
0x2
0x200000000
*/

class MainClass2
{
     static void Main()
     {
         int a = 1000;
         a <<= 4;
         Console.WriteLine(a);
     }
}

/*
Output:
16000
*/
4b9b3361

Ответ 1

<< - оператор сдвига слева; это берет двоичное представление значения и перемещает все биты "n" влево (за исключением "mod", см. "1" ), заполняя нули нулями.

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

1

Оператор сдвига по существу является "mod" шириной данных. Int - 32 бита, поэтому сдвиг влево 33 (в Int32) точно такой же, как сдвиг влево 1. Вы не получаете все нули. A long - 64 бит, поэтому сдвиг влево 33 дает другой ответ (исходное время 2 ^ 33).

2:

Каждый сдвиг влево (внутри ширины данных) одинаковый (для целых чисел) как x2 - так что < 4 равно x2x2x2x2 = x16.

Это простой двоичный файл:

0000000001 = 1

< < переходит в

0000000010 = 2

< < переходит в

0000000100 = 4

< < переходит в

0000001000 = 8

Ответ 2

Просто чтобы развернуть Marc немного ответить (Марк, не стесняйтесь включать это в свой, и я удалю этот ответ), это указано в разделе 7.8 спецификации:


Ниже перечислены предопределенные операторы сдвига.

Сдвиг влево:

  • int operator < (int x, int count);
  • uint operator < < (uint x, int count);
  • long operator < (long x, int count);
  • оператор ulong < (ulong x, int count);
< < оператор сдвигает x слева на количество бит, вычисленное, как описано ниже.

Стартовые разряды вне диапазона результата типа x отбрасываются, остальные бит сдвигаются влево, а разряды пустых разрядов младшего разряда устанавливаются на ноль.

Сдвиг вправо:

  • int operator → (int x, int count);
  • uint operator → (uint x, int count);
  • длинный оператор → (long x, int count);
  • ulong operator → (ulong x, int count);

Оператор → сдвигает x справа на количество бит, вычисленное, как описано ниже.

Когда x имеет тип int или long, младшие биты x отбрасываются, остальные бит сдвигаются вправо, а старшие разряды старшего разряда устанавливаются на ноль, если x неотрицателен и устанавливается в один, если х отрицательный.

Когда x имеет тип uint или ulong, младшие разряды x отбрасываются, остальные бит сдвигаются вправо, а старшие разряды старшего разряда устанавливаются на ноль.

Для предопределенных операторов число битов сдвига вычисляется следующим образом:

Когда тип x является int или uint, счетчик сдвига задается младшими пятью битами счета. Другими словами, подсчет сдвига вычисляется из count и 0x1F.

Когда тип x длинный или ulong, счетчик сдвига задается шестью битами младшего порядка. Другими словами, подсчет сдвига вычисляется из count и 0x3F.

Если итоговое значение сдвига равно нулю, операторы сдвига просто возвращают значение x.


Ответ 3

Несколько нот для начинающего программиста:

Зачем использовать операторы сдвига? Они, похоже, не очень много делают. Ну, есть две причины:

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

  • Поскольку они бывают быстрыми, для этого используется множество протоколов и стандартов. Например, операции с IP-адресом, проверка CRC, графические операции и т.д.

Ответ 4

"Оператор сдвига по существу является" mod "шириной данных".

Мусор! Если величина сдвига больше или равна ширине данных, результат равен undefined. Не ожидайте того же самого "мода", который вы видели, чтобы произойти с разными компиляторами или разными версиями одного и того же компилятора или в разных ситуациях смены в одной и той же программе или когда что-либо еще изменилось. Что означает "undefined".