Multiplication This describes the multiplication algorithm used by the MPI library. This is basically a standard "schoolbook" algorithm. It is slow -- O(mn) for m = #a, n = #b -- but easy to implement and verify. Basically, we run two nested loops, as illustrated here (R is the radix): k = 0 for j <- 0 to (#b - 1) for i <- 0 to (#a - 1) w = (a[j] * b[i]) + k + c[i+j] c[i+j] = w mod R k = w div R endfor c[i+j] = k; k = 0; endfor It is necessary that 'w' have room for at least two radix R digits. The product of any two digits in radix R is at most: (R - 1)(R - 1) = R^2 - 2R + 1 Since a two-digit radix-R number can hold R^2 - 1 distinct values, this insures that the product will fit into the two-digit register. To insure that two digits is enough for w, we must also show that there is room for the carry-in from the previous multiplication, and the current value of the product digit that is being recomputed. Assuming each of these may be as big as R - 1 (and no larger, certainly), two digits will be enough if and only if: (R^2 - 2R + 1) + 2(R - 1) <= R^2 - 1 Solving this equation shows that, indeed, this is the case: R^2 - 2R + 1 + 2R - 2 <= R^2 - 1 R^2 - 1 <= R^2 - 1 This suggests that a good radix would be one more than the largest value that can be held in half a machine word -- so, for example, as in this implementation, where we used a radix of 65536 on a machine with 4-byte words. Another advantage of a radix of this sort is that binary-level operations are easy on numbers in this representation. Here's an example multiplication worked out longhand in radix-10, using the above algorithm: a = 999 b = x 999 ------------- p = 98001 w = (a[jx] * b[ix]) + kin + c[ix + jx] c[ix+jx] = w % RADIX k = w / RADIX product ix jx a[jx] b[ix] kin w c[i+j] kout 000000 0 0 9 9 0 81+0+0 1 8 000001 0 1 9 9 8 81+8+0 9 8 000091 0 2 9 9 8 81+8+0 9 8 000991 8 0 008991 1 0 9 9 0 81+0+9 0 9 008901 1 1 9 9 9 81+9+9 9 9 008901 1 2 9 9 9 81+9+8 8 9 008901 9 0 098901 2 0 9 9 0 81+0+9 0 9 098001 2 1 9 9 9 81+9+8 8 9 098001 2 2 9 9 9 81+9+9 9 9 098001 ------------------------------------------------------------------ This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/.