Алгоритм деления очень больших чисел

Мне нужно написать алгоритм (я не могу использовать какую-либо стороннюю библиотеку, потому что это назначение), чтобы делить (целочисленное деление, плавающие части не важны) очень большие числа, например, 100 - 1000 цифр. Я нашел http://en.wikipedia.org/wiki/Fourier_division, но я не знаю, правильно ли это сделать. У вас есть предложения?

1) check divisior < dividend, otherwise it zero (because it will be an int division)
2) start from the left
3) get equal portion of digits from the dividend
4) if it divisor portion is still bigger, increment digits of dividend portion by 1
5) multiply divisor by 1-9 through the loop
6) when it exceeds the dividend portion, previous multiplier is the answer
7) repeat steps 3 to 5 until reaching to the end

Ответ 1

Кнут, Дональд, Искусство программирования, ISBN 0-201-89684-2, Том 2: Семинумерные алгоритмы, Раздел 4.3.1: Классические алгоритмы

Ответ 2

Я бы предположил, что разделение "длинного" пути, как в начальной школе, будет потенциальным путем. Я предполагаю, что вы получаете исходное число в виде строки, поэтому то, что вы делаете, анализирует каждую цифру. Пример:

Шаг 0:

   /-----------------
13 | 453453453435....

Шаг 1: "Сколько раз 13 идет в 4? 0

     0
   /-----------------
13 | 453453453435....

Шаг 2: "Сколько раз 13 переходов в 45? 3

     03
   /-----------------
13 | 453453453435....
   - 39
     --
      6

Шаг 3: "Сколько раз 13 заходит в 63? 4

и т.д. С этой стратегией вы можете иметь любую длину номера и на самом деле достаточно иметь достаточно цифр в памяти для int (divisor) и double (divend). (Предполагая, что я правильно понял эти условия). Вы сохраняете результат как последнюю цифру в строке результата.

Когда вы нажмете точку, в которой не осталось цифр, и вычисление не будет выполняться в 1 или более раз, вы возвращаете результат, который уже отформатирован как строка (поскольку он может быть потенциально больше, чем int).

Ответ 3

Самый простой алгоритм разделения для больших чисел - это сдвиг и вычитание.

if numerator is less than denominator then finish
shift denominator as far left as possible while it is still smaller than numerator
set bit in quotient for amount shifted
subtract shifted denominator from numerator
repeat
the numerator is now the remainder

Перемещение не должно быть буквальным. Например, вы можете написать алгоритм для вычитания сдвинутого слева значения из другого значения вместо фактического смещения всего значения до вычитания. То же самое касается сравнения.

Длительное разделение сложно реализовать, поскольку один из шагов в длинном делении - это длинное деление. Если делитель является int, вы можете сделать длинное разделение довольно легко.

Ответ 4

Вероятно, вы должны попробовать что-то вроде длинного деления, но вместо использования цифр вместо слов.

На высокоуровневом языке будет наиболее удобно рассматривать вашу цифру как половину размера вашего наибольшего целого числа с фиксированной точностью. Для метода длинного разделения вам нужно будет обрабатывать случай, когда ваш частичный промежуточный результат может быть отключен одним, поскольку ваше разделение с фиксированной точностью может обрабатывать только самую значительную часть вашего произвольного делителя.

Быстрее и сложнее использовать арифметику с произвольной точностью. Ознакомьтесь с соответствующей страницей wikipedia. В частности, метод Ньютона-Рафсона, когда он будет реализован тщательно, может гарантировать, что временная производительность вашего деления будет в пределах постоянного коэффициента умножения произвольной точности.

Ответ 5

Если бы часть вашего задания не была полностью оригинальной, я бы пошел с алгоритмом я (и я предполагаю, что вы) преподавался в старшей школе для выполнения большого разделения вручную.