Страница 1 из 1
Побитовый сдвиг
Добавлено: 12.03.2010 16:32:59
0minus273
Как реализовать неротационный (числа, которые "вытеснены" нулями не возвращаются в начало кода, а исчезают навеки) беззнаковый (в независимости от знака числа заполнение нулями) побитовый сдвиг longint'ов (32 бита) ?
[т.е., по сути, сделать аналог >>> из Явы;
input: longint, output: longint]
Встроенный в Паскале SHR не подходит, ибо: a SHR 32 = a (ротация), а дб a SHR 32+ = 0
Re: Побитовый сдвиг
Добавлено: 12.03.2010 16:44:32
hinst
чего? что-то я не вкуриваю. нет в паскале никакой ротации. там они исчезают
Re: Побитовый сдвиг
Добавлено: 12.03.2010 18:21:37
0minus273
uses crt;
var
kk : longint;
begin
kk := -3;
kk := kk SHR 32;
writeln (kk);
end.
у меня возвращает -3
Re: Побитовый сдвиг
Добавлено: 12.03.2010 19:47:25
hinst
не могёт быть. я точно помню, что когда я чего-то там делал полгода назад, оно сдвигалось с образующимися нулями
Re: Побитовый сдвиг
Добавлено: 12.03.2010 23:00:31
Sergei I. Gorelkin
Операторы shl/shr превращаются в одноименные команды процессора. Сдвиг 32-битного операнда на 32 бита на процессорах x86 возвращает исходный результат. Это особенность x86, не имеющая отношения к ротации.
Для ротации в FPC существуют ф-ции RolByte, RolWord, RolDWord, RolQWord, RorByte, RorWord, RorDword, RorQword.
Re: Побитовый сдвиг
Добавлено: 12.03.2010 23:38:02
Mr.Smart
Sergei I. GorelkinНе знал про эти функции. Век живи, век учись

Re: Побитовый сдвиг
Добавлено: 13.03.2010 01:47:43
0minus273
Sergei I. Gorelkin
А вот это интересно. Спасибо, не знала.
Однако же, если я не могу сейчас сменить процессор, как мне реализовать нужный сдвиг?
К сожалению, мой тн "опыт" позволяет мне думать только об обращении с рез-татом IntToBin, как с массивом чаров, а это, по-моему, не соответствует идее "дешевизны" побитовых операторов? Или я ошибаюсь?
Re: Побитовый сдвиг
Добавлено: 13.03.2010 02:25:36
Sergei I. Gorelkin
Достаточно просто добавить проверку величины сдвига и возвращать 0, если она 32 или более.
Re: Побитовый сдвиг
Добавлено: 13.03.2010 15: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: Побитовый сдвиг
Добавлено: 13.03.2010 23: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 00:52:35
alexrayne
Хотелось бы мне дожить до дня, когда компилятор научится превращать вызов функции в одну команду...
Свершиось Сергей, благую весть Вам несу - ifthen такая редкая функция в которой так оно и есть.!!!

Re: Побитовый сдвиг
Добавлено: 14.03.2010 02:47:07
Sergei I. Gorelkin
Ух ептыть, вот уж точно, знание - сила страшнее красоты

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