Вот одна идея, которая использует одно умножение и одну смену, поэтому она будет быстрее, чем разделение на большинстве систем. Так как ваши числители превышают 768 000 000 ~ = 30 бит, у нас не осталось много места в 32-битном слове, поэтому нам придется использовать 64-битное умножение.
Основная идея заключается в том, чтобы воспользоваться тем, что:
x/y == (x * k)/(y * k)
и делением на степени 2 является простым, быстрым сдвигом бит.
Так что, чтобы выбрать конкретный пример, предположим, что x = 700,000,000
и y = 47
(так что правильный коэффициент составляет 14 893 617). Чтобы избежать ошибок округления, наш сдвиг должен быть примерно размером с нашим самым большим возможным числителем - 30 бит. Найдите значение k
, что дает максимальное приближение к y * k = 2^30
, что в данном случае равно k = 22845571
. Затем x * k = 0x38D08C4CE6F500
. Сдвиг этого на 30 бит дает 0xE34231 = 14,893,617
, наш ожидаемый коэффициент. Возможно, вам понадобится добавить еще 1-2 бита для некоторых комбинаций числителя/знаменателя для целей округления, если только вы не выбрали значение 1 в вашем частном.
Упражнение затем создает таблицу поиска с соответствующими умножителями для каждого из возможных знаменателей.
EDIT: как указано в комментарии ниже, выбор k = (2^30 + y - 1)/y
должен давать лучшие и более последовательные результаты, чем просто k = round(2^30/y)
.
Где код, который вы hahve trid? – ErrorNotFoundException
Насколько велика числитель - т. Е. Ожидаемое значение, ограниченное некоторым значением? Возможно, двоичный поиск с использованием умножения (который все еще не очень быстрый, но быстрее, чем деление) - попробуйте '10 * Знаменатель', если это слишком мало, попробуйте' 100 * Знаменатель', если он слишком велик, попробуйте '55 * Знаменатель 'и т. д. ...Он примет шаги O (log2 (Quotient)) ... – twalberg
Числитель от 48 000 000 до 768 000 000 – user2478619