Search code examples
carraysmultiplication

Multiply a digit array by int in C


I have a very large number (>100 digits long) so it can't be stored as an int or even an unsigned long long (aka uint64_t). The array looks like this:
{5, 1, 2 ... 8, 6}
The array must contain single digit ints.


Question

What would be a simple, and most importantly efficient, way of multiplying this 'number' (keeping it as an array) by a single digit?

What I have tried

As I am fairly new to C, this code is not a masterpiece. Far from it.

struct returnpointer { int * pointer; int length; };

returnpointer mul_arrays(int * x, int y, int lengthof_x) {
    returnpointer result_end;
    int result[lengthof_x * 2 + 1];
    int final_result[lengthof_x * 2 + 1];
    int carry = 0;
    int j = 0;
    //multiply 'y' by all digits of x, which creates multidigit ints
    //and also reverses the direction of the array (to allow carrying)
    for (int i = lengthof_x; i >= 0; i--) {
        result[j] = x[i] * y;
        j++;
    }
    int i = 0;
    j = lengthof_x
    //this is the bit that doesn't work: it attempts to work out the carry
    //however after hours of debugging I can't get it to work.
    while (carry > 0 || i < lengthof_x + 1) {
        if (result[j] > 9) {
            carry = result[j] / 10;
            final_result[i] = result[j] % 10;
            final_result[i + 1] = carry;
        } else {
            final_result[i] = result[j];
            carry = 0;
        }
        i++;
        j--;
    }
    result_end.pointer = result;
    result_end.length  = i + 1;
    return result_end;
}

This code does not work properly. It is just an illustration of what I have tried (if it worked I would not be posting this).

In addition, it would be nice to know if the approach I am (trying to) use is the most efficient, as the program it will be incorporated into is very time-intensive so the faster the function the less time the entire program will take.

Thanks in advance.

EDIT:

My compiler is g++.


Solution

  • As requested, here is a code example that multiplies an array by a single digit. The array is little-endian. For a simple example, I have assumed that the array is of fixed length, a more complex one would allocate array memory and extend it if the array grows too big.

    #include <stdio.h>
    
    #define BIGLEN 20
    
    typedef struct {
        int length;
        int array[BIGLEN];
    } biggy_t;
    
    void bigmul(biggy_t *big, int mul)
    {
        int carry = 0, partial;
        for(int i = 0; i < big->length; i++) {
            partial = big->array[i] * mul + carry;
            big->array[i] = partial % 10;
            carry = partial / 10;
        }
        if(carry) {
            big->array[big->length] = carry;
            big->length++;
        }
    }
    
    void bigout(biggy_t *big)
    {
        for(int i = big->length-1; i >= 0; i--) {
            printf("%d", big->array[i]);
        }
    }
    
    int main(int argc, char *argv[])
    {
        biggy_t big = { 6, { 5, 1, 2, 3, 8, 6 }};   // reverse order
        bigout(&big);
        printf(" * 7 = ");
    
        bigmul(&big, 7);
        bigout(&big);
        printf("\n");
    }
    

    Program output

    683215 * 7 = 4782505
    

    I wrote a bignum implementation in which I can chose the radix. 10 or 100 for byte storage, much more for 32-bit storage. Sticking to a power of 10 makes the conversion to decimal output easier than a power of 2 radix, with a small time penalty for not using the full capacity of the storage type.