-
Как сделать в Делфи сложение с насыщением? Есть Д7 и Берлин.
Внезапно осознал что не знаю способов не использующих условных операторов...
Оно вообще такое умеет? Если нет, то из спортивного интереса - возможно ли сделать сей трюк булевыми операторами?
-
Если числа целые, а предел насчщения - степень двойки, то можно без и без условных операторов. В остальных случаях - нельзя
-
коррекция - степень двойки минус единица.
-
Допустим Byte/Word/Cardinal. Для "не меньше минимально возможного значения" есть отдельный термин?
А может ли что завалялся чуть более наглядный пример? С:
-
-
Хорошая ссылка. Даже очень. Большое спасибо!
У меня такая что-то поисковиком не находилась...
Пишут что хороший компилятор должен преобразовывать условие "было ли переполнение" чуть ли не в полторы команды ассемблера. Надо потестить делает ли такое Делфи...
А крайне любопытный код для оперирования сразу с блоком массива (наподобие MMX) выглядит ваще круто, но подозреваю возможно что даже "вручную" вышло бы быстрее... Тоже тестить))
-
function SAdd(a, b: cardinal): cardinal;
begin
Result:=a+b;
Result:=-(((a or b) and not Result) shr (SizeOf(Result)*8-1)) or Result;
end
не проверял
-
Sha © (19.01.18 11:05) [6]
Сопровождать такой код особенно приятно :)
-
ну, комментарии никто не отменял
-
и никто не пишет :)
-
если бы никто захотел, он бы написал
-
в [6] не захотел? ))
-
не захотел не из лени, а из уважения к автору,
дабы не портить ему удовольствие ))
-
хитро... мне-то точно доставил удовольствие: я попробовал подумать, как там написать комментарий
-
Да перевести-то на синтаксис Паскаля не проблема. Мне больше понравилась SatAddUnsigned8(). Истинно магия! ^_____^
Я об том что быстродействие под вопросом. И об том что хороший компилятор вроде как и так
function SAdd(a, b: cardinal): cardinal;
begin
Result:=a+b;
if (Result<a) then
Result:=#FFFFFFFF;
end;
должен сам соптимизировать в вызов CMOVcc...
А вот если делать ассемблерными вставками... Они оптимизатор не сбивают? Нормально ли inline'ятся? Как писать чтоб результат получался оптимальным?
Кстати никогда не умел переводить код ассемблера в "DB $....." для более старых версий Делфи - может кто научить?
А чего комментарии? Там есть даже рыба для комментария. :) "There are C-tricks to do saturated arithmetic as well. This little code does saturated addition on ..."
Только не "C-tricks", а "Bitwise-tricks".
-
> Вайрекс (19.01.18 21:02) [14]
Это другой little code,
но списать комментарий, конечно, можно, чтобы запутать себя, читающего.
-
[OFF]
Чего путать-то? И то и то "Bitwise-tricks". И то и то хрен в уме представишь. Но это и не нужно, как не нужно представлять дополнительный код и прочие "низости". :)
Вроде в данной ситуации более чем достаточно знать что это trick который (пусть и с некими оговорками) делает saturated, не?
[/OFF]
-
ну, тут каждый сам для себя решает, не или не не )
-
посмотрел код по ссылке,
с учетом [6] можно побайтовое насыщение сделать проще,
в 12 команд ассемблера:
function SatAdd8Sha(a, b: cardinal): cardinal;
var
c: cardinal;
begin;
c:=a+b;
a:=(a or b) and $80808080;
b:=not c and a;
a:=b;
b:=b shr 7;
c:=c-a or a;
a:=a-b;
a:=a or c;
Result:=a;
end;
без гарантий, особо не проверял
-
Аналогично можно реализовать побайтовое сложение без переноса
в 8 команд ассемблера:
function Add8Sha(a, b: cardinal): cardinal;
var
c: cardinal;
begin;
c:=a+b;
a:=(a or b) and $80808080 and not c;
Result:=c-a xor a;
end;
опять без гарантий
Немного изменная функция [18] примерно в 1.4 раза быстрее той,
что приводится по ссылке, это к вопросу о не - не не )