12

I need to write an algorithm(I cannot use any 3rd party library, because this is an assignment) to divide(integer division, floating parts are not important) very large numbers like 100 - 1000 digits. I found http://en.wikipedia.org/wiki/Fourier_division algorithm but I don't know if it's the right way to go. Do you have any suggestions?

1) check divisior < dividend, otherwise it's 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's 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
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
pocoa
  • 4,197
  • 9
  • 37
  • 45
  • "because this is an assignment"... Add the homework tag? – Neil N May 21 '10 at 17:28
  • 6
    If you can do long division on paper, you already know a good algorithm to solve this problem. – Carl Norum May 21 '10 at 17:31
  • @Neil: Well, I'm not expecting to receive a code sample. I'm just expecting to learn some math techniques to go beyond these language limitations. – pocoa May 21 '10 at 17:35
  • @pocoa: then you should add the homework tag. The tag denotes that you want help/ideas/advice, but you don't want the work done for you. – Neil N May 21 '10 at 17:37
  • 1
    @Carl: I think it's not that easy when you need to divide a 120 digits number with 75 :) This is why I'm asking. – pocoa May 21 '10 at 17:38
  • @pocoa, why not? The computer does all the hard work. You just need to set up the steps. There are answers below showing just that, in fact. – Carl Norum May 21 '10 at 17:46
  • @Carl: Yeah, I know :) I'm just looking for a better algorithm. – pocoa May 21 '10 at 17:52
  • @Carl: For example you can create your own solution to find the greatest common divisor by using loops, but using Euclidean Algorithm is the way to go. So basically I want to have an efficient solution. – pocoa May 21 '10 at 17:59
  • Try Newton-Raphson iteration. There are a couple other techniques that become slightly faster at huge numbers of digits (like in the millions of bits range), but Newton-Raphson is more straightforward and useful on so many other problems. – honestann Dec 31 '13 at 22:27

5 Answers5

12

I'd imagine that dividing the 'long' way like in grade school would be a potential route. I'm assuming you are receiving the original number as a string, so what you do is parse each digit. Example:

Step 0:

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

Step 1: "How many times does 13 go into 4? 0

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

Step 2: "How many times does 13 go into 45? 3

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

Step 3: "How many times does 13 go into 63? 4

etc etc. With this strategy, you can have any number length and only really have to hold enough digits in memory for an int (divisor) and double (dividend). (Assuming I got those terms right). You store the result as the last digit in your result string.

When you hit a point where no digits remain and the calculation wont go in 1 or more times, you return your result, which is already formatted as a string (because it could be potentially larger than an int).

Tejs
  • 40,736
  • 10
  • 68
  • 86
  • A long time ago I was reading the source to a MP library (http://gmplib.org/ I think). It used this approach for "mid sized" numbers (bigger than long, smaller that about 30 bytes), then switched to Fourier division for very large number. I would be interesting to see if that is still the approach used. – Rodney Schuler May 21 '10 at 17:53
  • @rschuler: So Fourier Division Algorithm can solve this problem, right? – pocoa May 21 '10 at 18:08
  • 9
    Your solution is only useful for small divisors. It's much more complicated when the divisor is also a big number. – pocoa May 22 '10 at 05:17
11

The easiest division algorithm to implement for large numbers is shift and subtract.

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

The shifting need not be literal. For example, you can write an algorithm to subtract a left shifted value from another value, instead of actually shifting the whole value left before subtracting. The same goes for comparison.

Long division is difficult to implement because one of the steps in long division is long division. If the divisor is an int, then you can do long division fairly easily.

drawnonward
  • 53,459
  • 16
  • 107
  • 112
10

Knuth, Donald, The Art of Computer Programming, ISBN 0-201-89684-2, Volume 2: Seminumerical Algorithms, Section 4.3.1: The Classical Algorithms

Doug Currie
  • 40,708
  • 1
  • 95
  • 119
  • Google for it; you will find lots of papers on line with "improvements" to the algorithm that Knuth so venerably documents. – Doug Currie May 21 '10 at 18:45
  • 5
    @pocoa, you really should get it from your school's library, it's an excellent book. – avakar May 21 '10 at 19:10
  • Does anyone happen to have a 1 to 1 naive but working implementation in a C like language of Knuth's algorithm D? I am confused by multiple steps like D1 introduction of new digit u_(m+n) which should be set to 0 if d = 1, but else? In step D4 is it if any digit is < 0 that I should add the b^(n+1) to all digits? The borrow I am adding to left, should that be a 1? Also my brain has troubles replacing u. D6 why is there a 0 multiplied to v_(n-1)? I am fully aware that I am simply too deft to understand him. I found https://skanthak.homepage.t-online.de/division.html but many optimizations etc. – Peheje Apr 13 '20 at 09:50
3

You should probably try something like long division, but using computer words instead of digits.

In a high-level language, it will be most convenient to consider your "digit" to be half the size of your largest fixed-precision integer. For the long division method, you will need to handle the case where your partial intermediate result may be off by one, since your fixed-precision division can only handle the most-significant part of your arbitrary-precision divisor.

There are faster and more complicated means of doing arbitrary-precision arithmetic. Check out the appropriate wikipedia page. In particular, the Newton-Raphson method, when implemented carefully, can ensure that the time performance of your division is within a constant factor of your arbitrary-precision multiplication.

comingstorm
  • 25,557
  • 3
  • 43
  • 67
1

Unless part of your assignment was to be completely original, I would go with the algorithm I (and I assume you) were taught in grade school for doing large division by hand.

Fletcher Moore
  • 13,558
  • 11
  • 40
  • 58