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 int
s.
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++.
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.