Побитовый сдвиг
Модератор: Модераторы
Побитовый сдвиг
Как реализовать неротационный (числа, которые "вытеснены" нулями не возвращаются в начало кода, а исчезают навеки) беззнаковый (в независимости от знака числа заполнение нулями) побитовый сдвиг longint'ов (32 бита) ?
[т.е., по сути, сделать аналог >>> из Явы;
input: longint, output: longint]
Встроенный в Паскале SHR не подходит, ибо: a SHR 32 = a (ротация), а дб a SHR 32+ = 0
[т.е., по сути, сделать аналог >>> из Явы;
input: longint, output: longint]
Встроенный в Паскале SHR не подходит, ибо: a SHR 32 = a (ротация), а дб a SHR 32+ = 0
чего? что-то я не вкуриваю. нет в паскале никакой ротации. там они исчезают
uses crt;
var
kk : longint;
begin
kk := -3;
kk := kk SHR 32;
writeln (kk);
end.
у меня возвращает -3
var
kk : longint;
begin
kk := -3;
kk := kk SHR 32;
writeln (kk);
end.
у меня возвращает -3
не могёт быть. я точно помню, что когда я чего-то там делал полгода назад, оно сдвигалось с образующимися нулями
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
Операторы shl/shr превращаются в одноименные команды процессора. Сдвиг 32-битного операнда на 32 бита на процессорах x86 возвращает исходный результат. Это особенность x86, не имеющая отношения к ротации.
Для ротации в FPC существуют ф-ции RolByte, RolWord, RolDWord, RolQWord, RorByte, RorWord, RorDword, RorQword.
Для ротации в FPC существуют ф-ции RolByte, RolWord, RolDWord, RolQWord, RorByte, RorWord, RorDword, RorQword.
Sergei I. Gorelkin
Не знал про эти функции. Век живи, век учись
Не знал про эти функции. Век живи, век учись
Sergei I. Gorelkin
А вот это интересно. Спасибо, не знала.
Однако же, если я не могу сейчас сменить процессор, как мне реализовать нужный сдвиг?
К сожалению, мой тн "опыт" позволяет мне думать только об обращении с рез-татом IntToBin, как с массивом чаров, а это, по-моему, не соответствует идее "дешевизны" побитовых операторов? Или я ошибаюсь?
А вот это интересно. Спасибо, не знала.
Однако же, если я не могу сейчас сменить процессор, как мне реализовать нужный сдвиг?
К сожалению, мой тн "опыт" позволяет мне думать только об обращении с рез-татом IntToBin, как с массивом чаров, а это, по-моему, не соответствует идее "дешевизны" побитовых операторов? Или я ошибаюсь?
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
Достаточно просто добавить проверку величины сдвига и возвращать 0, если она 32 или более.
Сдвиг 32-битного операнда на 32 бита на процессорах x86 возвращает исходный результат. Это особенность x86, не имеющая отношения к ротации.
это баг или фича? как сам интел это коментирует? оно на всех х86 или только интеловых?
а если сдвигать 2 раза на 16, оно правильно сдвинется?
Достаточно просто добавить проверку величины сдвига и возвращать 0, если она 32 или более.
+1, + надо включить поддержку -Cppentium2 для того чтоб ето условие быстро исполнялось.
кстати для нормального использования инструкций cmove есть какаято правильная и неправильна запись условий? насколько я понимаю
result := ifthen(rot > 31,0, value shr rot);
будет однозначно с использованием cmove ибо оба операнда вычислены, а вот аналог
if rot <= 31 then
result := value shr rot
else
result := 0;
уже неочевидно. Просветите Сергей.
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
alexrayne писал(а):это баг или фича? как сам интел это коментирует? оно на всех х86 или только интеловых?
Понятия не имею...
alexrayne писал(а):а если сдвигать 2 раза на 16, оно правильно сдвинется?
Должно сдвигаться правильно
alexrayne писал(а):+1, + надо включить поддержку -Cppentium2 для того чтоб ето условие быстро исполнялось.кстати для нормального использования инструкций cmove есть какаято правильная и неправильна запись условий? насколько я понимаюresult := ifthen(rot > 31,0, value shr rot);будет однозначно с использованием cmove ибо оба операнда вычислены, а вот аналог...
Хотелось бы мне дожить до дня, когда компилятор научится превращать вызов функции в одну команду...
Хотелось бы мне дожить до дня, когда компилятор научится превращать вызов функции в одну команду...
Свершиось Сергей, благую весть Вам несу - ifthen такая редкая функция в которой так оно и есть.!!!
- Sergei I. Gorelkin
- энтузиаст
- Сообщения: 1409
- Зарегистрирован: 24.07.2005 14:40:41
- Откуда: Зеленоград
Ух ептыть, вот уж точно, знание - сила страшнее красоты 
Я затрудняюсь сказать, как поведет себя обычное условие. Проще проверить, скомпилировав в ассемблер.
Но, при использовании ifthen, получается что мы выигрываем на ветвлении, но проигрываем на вычислении результата сдвига, т.к. вычисляем его даже если он не будет использован.
Я бы написал вот так:
Я затрудняюсь сказать, как поведет себя обычное условие. Проще проверить, скомпилировав в ассемблер.
Но, при использовании ifthen, получается что мы выигрываем на ветвлении, но проигрываем на вычислении результата сдвига, т.к. вычисляем его даже если он не будет использован.
Я бы написал вот так:
Код: Выделить всё
if rot > 31 then
value := 0;
value := value shr rot; // ноль останется нулем при любом rot.
спасибо за консультацию всем!
