Для каждого отдельного y
, существует последовательность операций (сложение, вычитание, сдвиг и бинарные), который делит x
на y
быстрее, чем (x86) инструкции деления. Нахождение этой последовательности, однако, не является простым и должно быть сделано заранее (возможно, если вы разделите на то же самое y
много).
Простой пример: разделить произвольный uint32
x
на 3, мы можем вместо того, чтобы рассчитать x * M
в uint64
типа и сдвиг вправо на 33 бит, где M
является волшебной константой, равной 2 /3 закругленных .
Следующий код (С) пытается 20 случайных uint32
значения с выше алгоритма и проверяет, что результат равен просто разделив на 3:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int step;
unsigned x, y1, y2;
unsigned const M = (1ULL << 33)/3 + 1;
srand (time (NULL));
for (step = 0; step < 20; step++)
{
x = (rand() << 30) | (rand() << 15) | rand();
y1 = x/3;
y2 = (x * 1ULL * M) >> 33;
printf ("%10u %10u %10u %s\n", x, y1, y2, y1 == y2 ? "true" : "false");
}
return 0;
}
Для получения дополнительной информации см Delight книга Хакера в целом, и свободно доступное дополнение - глава 10 здесь: hackersdelight.org/divcMore.pdf.
Если вы думаете, что если бы был способ сделать это в общем случае, это сделало бы сложность времени выполнения равным сумме сложения и вычитания (что, насколько мне известно, не является случай для ввода произвольного размера). –
Нет, нет пути – Amit
Какая проблема вы пытаетесь решить? –