-
При тестировании функций обнаружены ошибки, исправленные версии:
function SatAdd32Sha(a, b: cardinal): cardinal; begin; Result:=a+b; Result:=-((a and b or (a or b) and not Result) shr 31) or Result; end;
function SatAdd8Sha(a, b: cardinal): cardinal; var c: cardinal; begin; c:=a+b; a:=(a and b or (a or b) and not c) and $80808080; b:=a shr 7; a:=a+a; Result:=(c-a) or (a-b); end;
function Add8Sha(a, b: cardinal): cardinal; var c: cardinal; begin; c:=a+b; a:=(a and b or (a or b) and not c) and $80808080 ; a:=a+a; Result:=c-a; end;
Время работы SatAdd8Sha практически совпало с временем SatAdd8 (есть по приведенной выше ссылке):
function SatAdd8(a, b: cardinal): cardinal; const sign= $80808080; var dif, same: cardinal; begin; dif:=(a xor b) and sign; same:=a and b and sign; a:=a and not sign; b:=b and not sign; a:=a+b; same:=same or dif and a; same:=same + same - (same shr 7); Result:=a xor dif or same; end;
Можно немного докрутить и выиграть у нее несколько процентов, но это будут копейки. Так что извиняйте.
-
мм... А как именно тестите и на какой версии компилятора? Опции оптимизатора? А что с вариантом через просто if?
-
Тест простейший - полный перебор всех вариантов входных параметров для одного разряда (байта).
Компилятор - D7, оптимизация включена.
Можно немного ускорить, подглядывая в ассемблерный код. Разбиваем составные операторы на более простые и переставляем их как хотим.
Автору темы был интересен вариант без ифа, в данном случае может оказаться быстрее с ифом, не проверял.
-
Вот же, блин, сегодня не мой день.
Ответ на вопрос о тестировании заставил задуматься и погрустнеть) Из функций [20] верны только SatAdd32Sha и SatAdd8.
SatAdd8Sha и Add8Sha не верны. Они не учитывают, что перенос может распространиться на несколько разрядов. Тестирования одного разряда не достаточно.
|