C: двоичный левый поворот
Я написал этот маленький код на C:
int leftrotate (int x, int offset)
{
return ( x << offset ) | ( x >> (32 - offset));
}
Я ожидаю двоичного влево повернуть целое число, что означает, что я ожидаю переместить все биты от заданного смещения влево и выполнить сужение, если число слишком велико.
Например, когда я ввожу:
10100110100110100101000011111101 = 2795131133 = a69a50fd
Я ожидаю как возвращение:
01101001101001010000111111011010 = 1772425178 = 69a50fda
(обратите внимание, что шестнадцатеричное а в начале находится в конце, потому что я выбрал смещение 4 в этом конкретном примере)
Но вместо этого я получил:
11111111111111111111111111111010 = 4294967290 = fffffffa
- Есть идеи, откуда это может прийти или что я делаю не так?
- Я использую правильный
int
? я должен использоватьuint
вместо? Или, может бытьchar
? - Зависит ли это от архитектуры моего компьютера (32 или 64 бита)?
- Я думаю, это зависит от длины целого числа (поэтому я использую 32-битное число длины)?
Спасибо!!!
1 ответ
Его реализация определяет, является ли сдвиг вправо арифметическим или логическим сдвигом. В вашем случае это арифметический сдвиг, поэтому вы получаете расширение знака в >>
половина вашего выражения. Вам нужно положить unsigned
приведение или назначение, чтобы получить поведение, которое вы хотите.
unsigned int y = x;
return ( y << offset ) | ( y >> (32 - offset));
Есть идеи, откуда это может прийти или что я делаю не так?
Расширение знака из-за правого смещения подписанного значения.
Я использую правильный int? я должен использовать Uint вместо этого? Или, возможно, полукокса?
Изменение на unsigned int
в вашей функции подпись может быть самой простой, да.
Зависит ли это от архитектуры моего компьютера (32 или 64 бита)?
Нет, наверное нет.
Я думаю, это зависит от длины целого числа (поэтому я использую 32-битное число длины)?
Нет, наверное нет. Вы можете сделать вашу программу не зависящей от размера целого числа, хотя:
return (y << offset) | (y >> ((sizeof y * CHAR_BIT) - offset));