Замена деления умножением по-другому

Aleksandr Sharahov
Дата: 19.08.2017 11:13:19
Все знают о замене целочисленного деления умножением с использованием обратного reciprocal.
Пробую найти в сети упоминание о замене деления умножения с помощью обратного modular multiplicative inverse.
И не находится. Киньте ссылочку, люди добрые :-)

Вот пример, ищу нечто похожее (для C-шников - все числа и сдвиги беззнаковые):
function ShaDivMod10(ADividend: cardinal; var ARest: cardinal): cardinal;
const
  Shift= 1;
  Inverse= $CCCCCCCD;
  ToIndex= 28;
  Stamp: array[0..15] of cardinal= ($00000000, $00000000, $00000001, $33333334,
                                    $33333334, $00000001, $66666667, $66666667,
                                    $66666667, $9999999A, $9999999A, $9999999A,
                                    $CCCCCCCD, $CCCCCCCD, $CCCCCCCD, $00000001);
  Rest: array[0..15] of cardinal= (0, 0, 10, 8, 8, 10, 6, 6, 6, 4, 4, 4, 2, 2, 2, 10);
var
  i: cardinal;
begin;
  Result:=ADividend shr Shift * Inverse;
  i:=Result shr ToIndex;
  Result:=Result - Stamp[i];
  ARest:=Rest[i] + ADividend and (1 shl Shift - 1);
  end;


Краткое описание здесь: http://guildalfa.ru/alsha/node/34
mayton
Дата: 19.08.2017 15:16:16
Можно поискать похожий материал у:
1) Генри Уоррен - Алгоритмические трюки для программистов.
2) Степанов - От математики...

В обоих книгах есть масса технических хитростей в численных методах. Но будьте осторожны.
Часть этих методов дают приближенный результат. Например Уоррен приводит алгоритм деления
без "деления" который дает шум в младших разрядах частного.

Тоесть для бухгалтерского деления это может быть неприменимо.
Aleksandr Sharahov
Дата: 19.08.2017 15:23:06
Спасибо, сейчас гляну Степанова.
У Уоррена точно не было.
Aleksandr Sharahov
Дата: 19.08.2017 16:22:33
У Степанова тоже нет. Но интересно излагает.
mayton
Дата: 19.08.2017 16:51:51
Для тех кто хочет поучаствовать в разборе алгоритма.

Давайте переведем алгоритм из Паскале-Адо-подобного (о боже какая метафора) ЯП на язык математики.
Я не могу прочитать словами алгоритм в том виде как он записан. Ибо я не помню
как работает shr (что за хрень? Вроде сдвиг вправо? Вроде беззнаковый) и каков приоритет.
Каков приоритет операций здесь?
ADividend shr Shift * Inverse

Сначала сдвиг? Или сначала произведение.

И развернем операции в 1 на строку. Так будет их проще обсуждать.
Aleksandr Sharahov
Дата: 19.08.2017 17:16:35
mayton
Для тех кто хочет поучаствовать в разборе алгоритма.

Давайте переведем алгоритм из Паскале-Адо-подобного (о боже какая метафора) ЯП на язык математики.
Я не могу прочитать словами алгоритм в том виде как он записан. Ибо я не помню
как работает shr (что за хрень? Вроде сдвиг вправо? Вроде беззнаковый) и каков приоритет.
Каков приоритет операций здесь?
ADividend shr Shift * Inverse

Сначала сдвиг? Или сначала произведение.

И развернем операции в 1 на строку. Так будет их проще обсуждать.


shr - сдвиг вправо беззнаковый, shl - влево,
приоритет сдвигов такой же как у умножения,
значит, здесь операции выполняются слева направо, как написаны.
mayton
Дата: 19.08.2017 17:30:08
Правильно ли я понимаю что эта функция делит делимое (dividend) на 10 и возвращает остаток в Rest?
Aleksandr Sharahov
Дата: 19.08.2017 17:32:30
mayton
Правильно ли я понимаю что эта функция делит делимое (dividend) на 10 и возвращает остаток в Rest?


Да, правильно.

Забыл добавить, у бинарного and приоритет такой же как у сдвигов и умножения.
Aleksandr Sharahov
Дата: 19.08.2017 17:36:11
Эта функция делит делимое (dividend) на 10 и возвращает частное в Result, а остаток в Rest
mayton
Дата: 19.08.2017 17:40:31
А как "извне" получить доступ к Result? Он не объявлен в декларативной части функции.