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

Круговой сдвиг в c

Как работает следующий код и что означают переменные:

y = (x << shift) | (x >> (sizeof(x)*CHAR_BIT - shift));

Я нашел в статье с круговым сдвигом, но не объяснил, как это работает.

4b9b3361

Ответ 1

CHAR_BIT - количество бит на байт, должно быть всегда 8.

shift - это количество бит, которое вы хотите сдвинуть влево круговым способом, так что биты, которые сдвигаются влево, возвращаются вправо.

     1110 0000 << 2 results in:
     1000 0011

для примера:

   y = (x << 2) | (x >> (8 - 2));

Ответ 2

Это метод выполнения кругового сдвига. Предположим, что x - 8 бит.

+----+----+----+----+----+----+----+----+
| x1   x2   x3   x4   x5   x6   x7   x8 |
+----+----+----+----+----+----+----+----+

Тогда, сдвинув его на 3, получим:

+----+----+----+----+----+----+----+----+
| x4   x5   x6   x7   x8    0    0    0 |
+----+----+----+----+----+----+----+----+

Теперь CHAR_BIT*sizeof(x) совпадает с шириной x в битах, 8. Поэтому сдвиг x вправо на 8 - 3 дает нам:

+----+----+----+----+----+----+----+----+
| 0    0    0    0    0    x1   x2   x3 |
+----+----+----+----+----+----+----+----+

И беря ИЛИ, вы получаете:

+----+----+----+----+----+----+----+----+
| x4   x5   x6   x7   x8   x1   x2   x3 |
+----+----+----+----+----+----+----+----+

Это технически непереносимо, потому что оно не переносится на величину, равную ширине типа, поэтому, если сдвиг равен 8, сдвиг влево неправильный, и если сдвиг равен 0, тогда неправильная смена. Тем не менее, это работает на практике по всем трем общим поведениям при изменении ширины типа. (На практике величина сдвига уменьшается на некоторую по модулю - либо ширину бита типа, либо некоторое большее число.)

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

Сложные компиляторы фактически скомпилируют код до инструкции по вращению оборудования.

Ответ 3

(x << shift) 

Сдвигает "сдвиг" числа бит влево, возвращает сдвинутые биты

(x >> (sizeof(x)*CHAR_BIT - shift));

Делает пространство для размещения этих бит

CHAR_BIT - это количество бит в char, поэтому в основном 8. В C вы не обрабатываете один бит за раз, но как минимум, char количество бит. Итак, это гранулярность, которую вы получаете.

В общем случае

Для char, когда вы выполняете бит-поворот, вы делаете это в 8-битовом поле (1 байт)

Для int, когда вы выполняете поворот, вы делаете это в 32-битном поле (4 байта)


Пример с 8 бит:

x = 11010101
shift = 2

x << (2) = 01010100 //shifted right by 2 bits

= x >> ((1 * CHAR_BIT) - 2)
= x >> (6) 
= 00000011 //shifted left by 6bits

OR эти бит-мудры, чтобы дать

01010101
00000011
________
01010111

Это круговое смещенное значение на 2 бита

Ответ 4

Это работает только с неподписанными типами. В случае с подписанным отрицательным числом большинство левых бит будут заменены значением самого значимого бита (с 1-м) оператором смены сдвига ( " → " )

Я бы написал его вот так:

y = (x << shift) | ( (x >> (sizeof(x)*CHAR_BIT - shift)) & (0x7F >> (sizeof(x)*CHAR_BIT - shift) );

Здесь перед "|" мы подтверждаем, что первые n бит (n = sizeof (x) * CHAR_BIT - сдвиг) обнуляются. Мы также предполагаем, что x является коротким (2 байта). Таким образом, он также зависит от типа.