Страница 1 из 1

Побитовый сдвиг

СообщениеДобавлено: 12.03.2010 17:32:59
0minus273
Как реализовать неротационный (числа, которые "вытеснены" нулями не возвращаются в начало кода, а исчезают навеки) беззнаковый (в независимости от знака числа заполнение нулями) побитовый сдвиг longint'ов (32 бита) ?
[т.е., по сути, сделать аналог >>> из Явы;
input: longint, output: longint]

Встроенный в Паскале SHR не подходит, ибо: a SHR 32 = a (ротация), а дб a SHR 32+ = 0

Re: Побитовый сдвиг

СообщениеДобавлено: 12.03.2010 17:44:32
hinst
чего? что-то я не вкуриваю. нет в паскале никакой ротации. там они исчезают

Re: Побитовый сдвиг

СообщениеДобавлено: 12.03.2010 19:21:37
0minus273
uses crt;

var
kk : longint;

begin

kk := -3;
kk := kk SHR 32;
writeln (kk);

end.

у меня возвращает -3

Re: Побитовый сдвиг

СообщениеДобавлено: 12.03.2010 20:47:25
hinst
не могёт быть. я точно помню, что когда я чего-то там делал полгода назад, оно сдвигалось с образующимися нулями

Re: Побитовый сдвиг

СообщениеДобавлено: 13.03.2010 00:00:31
Sergei I. Gorelkin
Операторы shl/shr превращаются в одноименные команды процессора. Сдвиг 32-битного операнда на 32 бита на процессорах x86 возвращает исходный результат. Это особенность x86, не имеющая отношения к ротации.
Для ротации в FPC существуют ф-ции RolByte, RolWord, RolDWord, RolQWord, RorByte, RorWord, RorDword, RorQword.

Re: Побитовый сдвиг

СообщениеДобавлено: 13.03.2010 00:38:02
Mr.Smart
Sergei I. Gorelkin
Не знал про эти функции. Век живи, век учись :wink:

Re: Побитовый сдвиг

СообщениеДобавлено: 13.03.2010 02:47:43
0minus273
Sergei I. Gorelkin
А вот это интересно. Спасибо, не знала.

Однако же, если я не могу сейчас сменить процессор, как мне реализовать нужный сдвиг?
К сожалению, мой тн "опыт" позволяет мне думать только об обращении с рез-татом IntToBin, как с массивом чаров, а это, по-моему, не соответствует идее "дешевизны" побитовых операторов? Или я ошибаюсь?

Re: Побитовый сдвиг

СообщениеДобавлено: 13.03.2010 03:25:36
Sergei I. Gorelkin
Достаточно просто добавить проверку величины сдвига и возвращать 0, если она 32 или более.

Re: Побитовый сдвиг

СообщениеДобавлено: 13.03.2010 16:11:19
alexrayne
Сдвиг 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;
уже неочевидно. Просветите Сергей.

Re: Побитовый сдвиг

СообщениеДобавлено: 14.03.2010 00:25:49
Sergei I. Gorelkin
alexrayne писал(а):это баг или фича? как сам интел это коментирует? оно на всех х86 или только интеловых?

Понятия не имею...
alexrayne писал(а):а если сдвигать 2 раза на 16, оно правильно сдвинется?

Должно сдвигаться правильно

alexrayne писал(а):+1, + надо включить поддержку -Cppentium2 для того чтоб ето условие быстро исполнялось.кстати для нормального использования инструкций cmove есть какаято правильная и неправильна запись условий? насколько я понимаюresult := ifthen(rot > 31,0, value shr rot);будет однозначно с использованием cmove ибо оба операнда вычислены, а вот аналог...

Хотелось бы мне дожить до дня, когда компилятор научится превращать вызов функции в одну команду...

Re: Побитовый сдвиг

СообщениеДобавлено: 14.03.2010 01:52:35
alexrayne
Хотелось бы мне дожить до дня, когда компилятор научится превращать вызов функции в одну команду...

Свершиось Сергей, благую весть Вам несу - ifthen такая редкая функция в которой так оно и есть.!!! :D

Re: Побитовый сдвиг

СообщениеДобавлено: 14.03.2010 03:47:07
Sergei I. Gorelkin
Ух ептыть, вот уж точно, знание - сила страшнее красоты :D

Я затрудняюсь сказать, как поведет себя обычное условие. Проще проверить, скомпилировав в ассемблер.
Но, при использовании ifthen, получается что мы выигрываем на ветвлении, но проигрываем на вычислении результата сдвига, т.к. вычисляем его даже если он не будет использован.
Я бы написал вот так:
Код: Выделить всё
if rot > 31 then
  value := 0;
value := value shr rot;   // ноль останется нулем при любом rot.

Re: Побитовый сдвиг

СообщениеДобавлено: 14.03.2010 19:24:34
0minus273
спасибо за консультацию всем!