Lably
Skip to content

Division algorithm

Method for division with remainder

  • 24 min read
  • 7 chapters

Related on Lably

Through Algorithm, Integer and Quotient

Division algorithms fall into two main categories: slow division and fast division. Slow division algorithms produce one digit of the final quotient per iteration. Examples of slow division include restoring, non-performing restoring, non-restoring, and SRT division. Fast division methods start with a close approximation to the final quotient and produce twice as many digits of the final quotient on each iteration. Newton–Raphson and Goldschmidt algorithms fall into this category.

Variants of these algorithms allow using fast multiplication algorithms. It results that, for large integers, the computer time needed for a division is the same, up to a constant factor, as the time needed for a multiplication, whichever multiplication algorithm is used.

Discussion will refer to the form N/D=(Q,R), where

is the input, and

is the output.

Division by repeated subtraction

The simplest division algorithm, historically incorporated into a greatest common divisor algorithm presented in Euclid's Elements, Book VII, Proposition 1, finds the remainder given two positive integers using only subtractions and comparisons:

<span id="mwNQ"></span><span class="kr" id="mwNg">function</span><span class="w" id="mwNw"> </span><span class="nf" id="mwOA">divide_unsigned</span><span class="p" id="mwOQ">(</span><span class="nv" id="mwOg">N</span><span class="p" id="mwOw">,</span><span class="w" id="mwPA"> </span><span class="nv" id="mwPQ">D</span><span class="p" id="mwPg">)</span> <span class="w" id="mwPw"> </span><span class="kr" id="mwQA">if</span><span class="w" id="mwQQ"> </span><span class="nv" id="mwQg">D</span><span class="w" id="mwQw"> </span><span class="o" id="mwRA">=</span><span class="w" id="mwRQ"> </span><span class="mi" id="mwRg">0</span><span class="w" id="mwRw"> </span><span class="kr" id="mwSA">then</span><span class="w" id="mwSQ"> </span><span class="nb" id="mwSg">error</span><span class="p" id="mwSw">(</span><span class="nv" id="mwTA">DivisionByZero</span><span class="p" id="mwTQ">)</span><span class="w" id="mwTg"> </span><span class="kr" id="mwTw">end</span> <span class="w" id="mwUA"> </span><span class="nv" id="mwUQ">R</span><span class="w" id="mwUg"> </span><span class="p" id="mwUw">:</span><span class="err" id="mwVA">=</span><span class="w" id="mwVQ"> </span><span class="py" id="mwVg">N</span> <span class="w" id="mwVw"> </span><span class="nv" id="mwWA">Q</span><span class="w" id="mwWQ"> </span><span class="p" id="mwWg">:</span><span class="err" id="mwWw">=</span><span class="w" id="mwXA"> </span><span class="err" id="mwXQ">0</span> <span class="w" id="mwXg"> </span><span class="py" id="mwXw">while</span><span class="w" id="mwYA"> </span><span class="nv" id="mwYQ">R</span><span class="w" id="mwYg"> </span><span class="err" id="mwYw">≥</span><span class="w" id="mwZA"> </span><span class="nv" id="mwZQ">D</span><span class="w" id="mwZg"> </span><span class="kr" id="mwZw">do</span> <span class="w" id="mwaA"> </span><span class="nv" id="mwaQ">R</span><span class="w" id="mwag"> </span><span class="p" id="mwaw">:</span><span class="err" id="mwbA">=</span><span class="w" id="mwbQ"> </span><span class="py" id="mwbg">R</span><span class="w" id="mwbw"> </span><span class="err" id="mwcA">−</span><span class="w" id="mwcQ"> </span><span class="nv" id="mwcg">D</span> <span class="w" id="mwcw"> </span><span class="nv" id="mwdA">Q</span><span class="w" id="mwdQ"> </span><span class="p" id="mwdg">:</span><span class="err" id="mwdw">=</span><span class="w" id="mweA"> </span><span class="py" id="mweQ">Q</span><span class="w" id="mweg"> </span><span class="o" id="mwew">+</span><span class="w" id="mwfA"> </span><span class="mi" id="mwfQ">1</span> <span class="w" id="mwfg"> </span><span class="kr" id="mwfw">end</span> <span class="w" id="mwgA"> </span><span class="kr" id="mwgQ">return</span><span class="w" id="mwgg"> </span><span class="p" id="mwgw">(</span><span class="nv" id="mwhA">Q</span><span class="p" id="mwhQ">,</span><span class="w" id="mwhg"> </span><span class="nv" id="mwhw">R</span><span class="p" id="mwiA">)</span> <span class="kr" id="mwiQ">end</span>

The proof that the quotient and remainder exist and are unique (described at Euclidean division) gives rise to a complete division algorithm, applicable to both negative and positive numbers, using additions, subtractions, and comparisons:

<span id="mwjg"></span><span class="kr" id="mwjw">function</span><span class="w" id="mwkA"> </span><span class="nf" id="mwkQ">divide</span><span class="p" id="mwkg">(</span><span class="nv" id="mwkw">N</span><span class="p" id="mwlA">,</span><span class="w" id="mwlQ"> </span><span class="nv" id="mwlg">D</span><span class="p" id="mwlw">)</span> <span class="w" id="mwmA"> </span><span class="kr" id="mwmQ">if</span><span class="w" id="mwmg"> </span><span class="nv" id="mwmw">D</span><span class="w" id="mwnA"> </span><span class="o" id="mwnQ">=</span><span class="w" id="mwng"> </span><span class="mi" id="mwnw">0</span><span class="w" id="mwoA"> </span><span class="kr" id="mwoQ">then</span><span class="w" id="mwog"> </span><span class="nb" id="mwow">error</span><span class="p" id="mwpA">(</span><span class="nv" id="mwpQ">DivisionByZero</span><span class="p" id="mwpg">)</span><span class="w" id="mwpw"> </span><span class="kr" id="mwqA">end</span> <span class="w" id="mwqQ"> </span><span class="kr" id="mwqg">if</span><span class="w" id="mwqw"> </span><span class="nv" id="mwrA">D</span><span class="w" id="mwrQ"> </span><span class="o" id="mwrg"><</span><span class="w" id="mwrw"> </span><span class="mi" id="mwsA">0</span><span class="w" id="mwsQ"> </span><span class="kr" id="mwsg">then</span><span class="w" id="mwsw"> </span> <span class="w" id="mwtA"> </span><span class="p" id="mwtQ">(</span><span class="nv" id="mwtg">Q</span><span class="p" id="mwtw">,</span><span class="w" id="mwuA"> </span><span class="nv" id="mwuQ">R</span><span class="p" id="mwug">)</span><span class="w" id="mwuw"> </span><span class="p" id="mwvA">:</span><span class="o" id="mwvQ">=</span><span class="w" id="mwvg"> </span><span class="nf" id="mwvw">divide</span><span class="p" id="mwwA">(</span><span class="nv" id="mwwQ">N</span><span class="p" id="mwwg">,</span><span class="w" id="mwww"> </span><span class="err" id="mwxA">−</span><span class="nv" id="mwxQ">D</span><span class="p" id="mwxg">)</span> <span class="w" id="mwxw"> </span><span class="kr" id="mwyA">return</span><span class="w" id="mwyQ"> </span><span class="p" id="mwyg">(</span><span class="err" id="mwyw">−</span><span class="nv" id="mwzA">Q</span><span class="p" id="mwzQ">,</span><span class="w" id="mwzg"> </span><span class="nv" id="mwzw">R</span><span class="p" id="mw0A">)</span><span class="w" id="mw0Q"> </span> <span class="w" id="mw0g"> </span><span class="kr" id="mw0w">end</span> <span class="w" id="mw1A"> </span><span class="kr" id="mw1Q">if</span><span class="w" id="mw1g"> </span><span class="nv" id="mw1w">N</span><span class="w" id="mw2A"> </span><span class="o" id="mw2Q"><</span><span class="w" id="mw2g"> </span><span class="mi" id="mw2w">0</span><span class="w" id="mw3A"> </span><span class="kr" id="mw3Q">then</span> <span class="w" id="mw3g"> </span><span class="p" id="mw3w">(</span><span class="nv" id="mw4A">Q</span><span class="p" id="mw4Q">,</span><span class="w" id="mw4g"> </span><span class="nv" id="mw4w">R</span><span class="p" id="mw5A">)</span><span class="w" id="mw5Q"> </span><span class="p" id="mw5g">:</span><span class="o" id="mw5w">=</span><span class="w" id="mw6A"> </span><span class="nf" id="mw6Q">divide</span><span class="p" id="mw6g">(</span><span class="err" id="mw6w">−</span><span class="nv" id="mw7A">N</span><span class="p" id="mw7Q">,</span><span class="w" id="mw7g"> </span><span class="nv" id="mw7w">D</span><span class="p" id="mw8A">)</span> <span class="w" id="mw8Q"> </span><span class="kr" id="mw8g">if</span><span class="w" id="mw8w"> </span><span class="nv" id="mw9A">R</span><span class="w" id="mw9Q"> </span><span class="o" id="mw9g">=</span><span class="w" id="mw9w"> </span><span class="mi" id="mw-A">0</span><span class="w" id="mw-Q"> </span><span class="kr" id="mw-g">then</span><span class="w" id="mw-w"> </span> <span class="w" id="mw_A"> </span><span class="kr" id="mw_Q">return</span><span class="w" id="mw_g"> </span><span class="p" id="mw_w">(</span><span class="err" id="mwAQA">−</span><span class="nv" id="mwAQE">Q</span><span class="p" id="mwAQI">,</span><span class="w" id="mwAQM"> </span><span class="mi" id="mwAQQ">0</span><span class="p" id="mwAQU">)</span> <span class="w" id="mwAQY"> </span><span class="kr" id="mwAQc">else</span> <span class="w" id="mwAQg"> </span><span class="c1" id="mwAQk">-- Example: N = -7, D = 3</span> <span class="w" id="mwAQo"> </span><span class="c1" id="mwAQs">-- divide(-N, D) = divide(7, 3) = (2, 1)</span> <span class="w" id="mwAQw"> </span><span class="c1" id="mwAQ0">-- R ≠ 0, so return (-2 - 1, 3 - 1) = (-3, 2)</span> <span class="w" id="mwAQ4"> </span><span class="c1" id="mwAQ8">-- Check: (-3)*3 + 2 = -7</span> <span class="w" id="mwARA"> </span><span class="kr" id="mwARE">return</span><span class="w" id="mwARI"> </span><span class="p" id="mwARM">(</span><span class="err" id="mwARQ">−</span><span class="nv" id="mwARU">Q</span><span class="w" id="mwARY"> </span><span class="err" id="mwARc">−</span><span class="w" id="mwARg"> </span><span class="mi" id="mwARk">1</span><span class="p" id="mwARo">,</span><span class="w" id="mwARs"> </span><span class="nv" id="mwARw">D</span><span class="w" id="mwAR0"> </span><span class="err" id="mwAR4">−</span><span class="w" id="mwAR8"> </span><span class="nv" id="mwASA">R</span><span class="p" id="mwASE">)</span><span class="w" id="mwASI"> </span> <span class="w" id="mwASM"> </span><span class="kr" id="mwASQ">end</span> <span class="w" id="mwASU"> </span><span class="kr" id="mwASY">end</span> <span class="w" id="mwASc"> </span><span class="c1" id="mwASg">-- At this point, N ≥ 0 and D > 0</span> <span class="w" id="mwASk"> </span><span class="kr" id="mwASo">return</span><span class="w" id="mwASs"> </span><span class="nf" id="mwASw">divide_unsigned</span><span class="p" id="mwAS0">(</span><span class="nv" id="mwAS4">N</span><span class="p" id="mwAS8">,</span><span class="w" id="mwATA"> </span><span class="nv" id="mwATE">D</span><span class="p" id="mwATI">)</span> <span class="kr" id="mwATM">end</span>

This procedure always produces R ≥ 0. Although very simple, it takes Ω(Q) steps, and so is exponentially slower than even slow division algorithms like long division. It is useful if Q is known to be small (being an output-sensitive algorithm), and can serve as an executable specification.

Alternative implementation

An alternative implementation increments a remainder and resets it when it reaches the divisor.

For x,y∈N0, the algorithm computes q,r such that x=qy+r, with 0≤r<y:

div⁡(x,y)=⌊x/y⌋
xmody=x−y⌊x/y⌋

Consider this code in Python:

<span id="mwAUc"></span><span class="k" id="mwAUg">def</span><span class="w" id="mwAUk"> </span><span class="nf" id="mwAUo">divide_unsigned2</span><span class="p" id="mwAUs">(</span><span class="n" id="mwAUw">numerator</span><span class="p" id="mwAU0">:</span> <span class="nb" id="mwAU4">int</span><span class="p" id="mwAU8">,</span> <span class="n" id="mwAVA">denominator</span><span class="p" id="mwAVE">:</span> <span class="nb" id="mwAVI">int</span><span class="p" id="mwAVM">)</span> <span class="o" id="mwAVQ">-></span> <span class="nb" id="mwAVU">tuple</span><span class="p" id="mwAVY">[</span><span class="nb" id="mwAVc">int</span><span class="p" id="mwAVg">,</span> <span class="nb" id="mwAVk">int</span><span class="p" id="mwAVo">]</span> <span class="n" id="mwAVs">quotient</span><span class="p" id="mwAVw">:</span> <span class="nb" id="mwAV0">int</span> <span class="o" id="mwAV4">=</span> <span class="mi" id="mwAV8">0</span> <span class="n" id="mwAWA">remainder</span><span class="p" id="mwAWE">:</span> <span class="nb" id="mwAWI">int</span> <span class="o" id="mwAWM">=</span> <span class="mi" id="mwAWQ">0</span> <span class="k" id="mwAWU">for</span> <span class="n" id="mwAWY">_</span> <span class="ow" id="mwAWc">in</span> <span class="nb" id="mwAWg">range</span><span class="p" id="mwAWk">(</span><span class="n" id="mwAWo">numerator</span><span class="p" id="mwAWs">):</span> <span class="n" id="mwAWw">remainder</span> <span class="o" id="mwAW0">+=</span> <span class="mi" id="mwAW4">1</span> <span class="k" id="mwAW8">if</span> <span class="n" id="mwAXA">remainder</span> <span class="o" id="mwAXE">==</span> <span class="n" id="mwAXI">denominator</span><span class="p" id="mwAXM">:</span> <span class="n" id="mwAXQ">quotient</span> <span class="o" id="mwAXU">+=</span> <span class="mi" id="mwAXY">1</span> <span class="n" id="mwAXc">remainder</span> <span class="o" id="mwAXg">=</span> <span class="mi" id="mwAXk">0</span> <span class="k" id="mwAXo">return</span> <span class="n" id="mwAXs">quotient</span><span class="p" id="mwAXw">,</span> <span class="n" id="mwAX0">remainder</span>

Notes

  • Special cases are
xmod1=0 and
xmod0=x.
  • Variable quotient is never read. So when its assignments —highlighted— are removed from the code and quotient is removed from the output list, divide_unsigned2, like divide_unsigned, still will compute xmody.

Alternative implementation as counter machine
A simple counter machine (CM) can be based on the alternative implementation. The CM instructions are

  • Z (n): Replace rn by 0.
  • S (n): Add 1 to rn.
  • J (m, n, q): If rm = rn, jump to the qth instruction; otherwise go on to the next instruction in the program.

The counter machine program is

<span id="mwAbQ"></span>1: J(1,5,0) 2: S(4) 3: J(4,2,6) 4: S(5) 5: J(0,0,1) 6: S(3) 7: Z(4) 8: S(5) 9: J(0,0,1)

After the CM finishes the computation on initial register values R1=N, R2=D (remaining registers = 0),

register R3 holds the (integer part of the) quotient of the division N/D, and
register R4 holds the remainder.

Sign in to keep reading

6 more chapters are free with a Lably account.

More in Computing and communication