7

Is there an algorithm for accurately multiplying two arbitrarily long integers together? The language I am working with is limited to 64-bit unsigned integer length (maximum integer size of 18446744073709551615). Realistically, I would like to be able to do this by breaking up each number, processing them somehow using the unsigned 64-bit integers, and then being able to put them back together in to a string (which would solve the issue of multiplied result storage).

Any ideas?

Valdemarick
  • 247
  • 2
  • 4
  • 10
  • Check this > [an algorithm to multiply of Large numbers](http://www.msccomputerscience.com/2014/08/design-algorithm-to-multiply-of-large.html) – ARJUN Sep 20 '14 at 06:32

7 Answers7

14

Most languages have functions or libraries that do this, usually called a Bignum library (GMP is a good one.)

If you want to do it yourself, I would do it the same way that people do long multiplication on paper. To do this you could either work with strings containing the number, or do it in binary using bitwise operations.

Example:

  45
 x67
 ---
 315
+270
----
 585

Or in binary:

   101
  x101
  ----
   101
  000
+101
------
 11001

Edit: After doing it in binary I realized that it would be much simpler (and faster of course) to code using bitwise operations instead of strings containing the base-10 numbers. I've edited my binary multiplying example to show a pattern: for each 1-bit in the bottom number, add the top number, bit-shifted left the position of the 1-bit times to a variable. At the end, that variable will contain the product.

To store the product, you'll have to have two 64-bit numbers and imagine one of them being the first 64 bits and the other one the second 64 bits of the product. You'll have to write code that carries the addition from bit 63 of the second number to bit 0 of the first number.

Paige Ruten
  • 172,675
  • 36
  • 177
  • 197
  • 3
    Congratulations, you've just reinvented 'peasant multiplication'. ;) http://en.wikipedia.org/wiki/Multiplication_algorithm#Peasant_or_binary_multiplication – Nick Johnson Oct 11 '08 at 09:55
  • 4
    There are much faster algorithms for multiplication than "peasant multiplicaton" – DanielOfTaebl Sep 20 '11 at 09:18
5

If you can't use an existing bignum library like GMP, check out Wikipedia's article on binary multiplication with computers. There are a number of good, efficient algorithms for this.

Nick Johnson
  • 100,655
  • 16
  • 128
  • 198
3

The simplest way would be to use the schoolbook mechanism, splitting your arbitrarily sized numbers into chunks of 32-bit each.

Given A B C D * E F G H (each chunk 32-bit, for a total 128 bit)
You need an output array 9 dwords wide. Set Out[0..8] to 0

You'd start by doing: H * D + out[8] => 64 bit result.
Store the low 32-bits in out[8] and take the high 32-bits as carry
Next: (H * C) + out[7] + carry
Again, store low 32-bit in out[7], use the high 32-bits as carry
after doing H*A + out[4] + carry, you need to continue looping until you have no carry.

Then repeat with G, F, E.
For G, you'd start at out[7] instead of out[8], and so forth.

Finally, walk through and convert the large integer into digits (which will require a "divide large number by a single word" routine)

2

Yes, you do it using a datatype that is effectively a string of digits (just like a normal 'string' is a string of characters). How you do this is highly language-dependent. For instance, Java uses BigDecimal. What language are you using?

Draemon
  • 33,955
  • 16
  • 77
  • 104
  • Freebasic, which I do not think has this feature built in. I am willing to write it though, if I could get an idea of the algorithm used. – Valdemarick Oct 10 '08 at 23:58
2

This is often given as a homework assignment. The algorithm you learned in grade school will work. Use a library (several are mentioned in other posts) if you need this for a real application.

ejgottl
  • 2,809
  • 19
  • 18
1

Here is my code piece in C. Good old multiply method

char *multiply(char s1[], char s2[]) {
    int l1 = strlen(s1);
    int l2 = strlen(s2);
    int i, j, k = 0, c = 0;
    char *r = (char *) malloc (l1+l2+1); // add one byte for the zero terminating string
    int temp;

    strrev(s1);
    strrev(s2);
    for (i = 0;i <l1+l2; i++) {
        r[i] = 0 + '0';
    }

    for (i = 0; i <l1; i ++) {
        c = 0; k = i;
        for (j = 0; j < l2; j++) {
            temp = get_int(s1[i]) * get_int(s2[j]);
            temp = temp + c + get_int(r[k]);
            c = temp /10;
            r[k] = temp%10 + '0';

            k++;
        }
        if (c!=0) {
            r[k] = c + '0';
            k++;
        }
    }

    r[k] = '\0';
    strrev(r);
    return r;
}
phuclv
  • 37,963
  • 15
  • 156
  • 475
ron
  • 11
  • 1
1

    //Here is a JavaScript version of an Karatsuba Algorithm running with less time than the usual multiplication method
    
    function range(start, stop, step) {
        if (typeof stop == 'undefined') {
            // one param defined
            stop = start;
            start = 0;
        }
        if (typeof step == 'undefined') {
            step = 1;
        }
        if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
            return [];
        }
        var result = [];
        for (var i = start; step > 0 ? i < stop : i > stop; i += step) {
            result.push(i);
        }
        return result;
    };
    function zeroPad(numberString, zeros, left = true) {
        //Return the string with zeros added to the left or right.
        for (var i in range(zeros)) {
            if (left)
                numberString = '0' + numberString
            else
                numberString = numberString + '0'
        }
    
        return numberString
    }
    function largeMultiplication(x, y) {
        x = x.toString();
        y = y.toString();
    
        if (x.length == 1 && y.length == 1)
            return parseInt(x) * parseInt(y)
    
        if (x.length < y.length)
            x = zeroPad(x, y.length - x.length);
    
        else
            y = zeroPad(y, x.length - y.length);
    
        n = x.length
        j = Math.floor(n/2);
    
        //for odd digit integers
        if ( n % 2 != 0)
            j += 1    
        var BZeroPadding = n - j
        var AZeroPadding = BZeroPadding * 2
    
        a = parseInt(x.substring(0,j));
        b = parseInt(x.substring(j));
        c = parseInt(y.substring(0,j));
        d = parseInt(y.substring(j));
    
        //recursively calculate
        ac = largeMultiplication(a, c)
        bd = largeMultiplication(b, d)
        k = largeMultiplication(a + b, c + d)
        A = parseInt(zeroPad(ac.toString(), AZeroPadding, false))
        B = parseInt(zeroPad((k - ac - bd).toString(), BZeroPadding, false))
        return A + B + bd
    }
    //testing the function here
    example = largeMultiplication(12, 34)
    console.log(example)
  • your code has a lot of syntax errors that result in compilation failure. I've fixed some of them but the code still doesn't work – phuclv Oct 18 '18 at 09:14
  • are you sure this works? why do you remove the js tag so that people can verify? – phuclv Oct 20 '18 at 05:15
  • that wasn't deliberate, I just replaced the code afresh with the working one. You can create a plunkr for this or jsfiddle – Pianistprogrammer Oct 21 '18 at 04:41