T
Tomás Ó hÉilidhe
I have a radix, and I have a string of digits representing a number:
unsigned digits[] = {1,5,12,7,9,10,4,8};
The radix is 13. The most significant digit is on the left. So the
actual value of this number is calculable as:
1*(13^0) + 5*(13^1) + 12*(13^2) + 7*(13^3) + 9*(13^4) + 10*(13^5) +
4*(13^6) + 8(13^7)
I'm stuck with this format, I can't change it. As parameters to my
function, I get the radix, the digit array, and a pointer to the last
digit. So altogether its:
struct Number {
unsigned radix;
unsigned *p_flast_digit;
unsigned digits[N];
};
OK now so what I want to do is divide this number by a particular
divisor. The divisor is held in a normal integer type (not as a string
of digits). Of course in order to perform this calculation, I could
simply use the expression I show above to convert the digit string to
a fully-fledge integer type, but I can't do that because the number is
*ridiculously* big, bigger than can be stored in a 64-Bit number.
So I got out a pen and paper and thought about ways of achieving this.
I ended up writing out a long-division sum by hand and then analysing
the steps I made to calculate it. I then started coding my method.
So basically it works as follows:
* I have a pointer to the most significant digit (which is at the end
of the string of digits). Let's call this pointer simply "p".
* I have an integer variable that holds a "sum of digits", and it
starts off as zero. What happens is I add "*p" to the sum_of_digits,
and then I decrement "p". I keep doing this in a loop until
sum_of_digits becomes greater than or equal to divisor, so the loop
would be:
unsigned sum_of_digits = 0;
for (;
{
sum_of_digits += *p;
if (sum_of_digits >= divisor) break;
--p;
}
(Of course I need to make allowances for running out of digits but
bear with me)
* When sum_of_digits becomes greater than or equal to the divisor, I
perform a division (i.e. sum_of_digits / divisor).
* I take the result of this division and I use it as the most
significant digit of the result. Then I take the remainder and I
prefix it to the original number replacing the digits I've just
divided into (exactly how you'd do it with a pen and paper). Then I
start again, dividing the divisor into this new number, taking down
extra digits as I need them. The result I get from the second division
is used as the second most significant digit of the result. Perform
another division, I get the third most significant digit, and so on.
Is my pen-and-paper approach a bit ridiculous, or is it a good way of
going about this?
unsigned digits[] = {1,5,12,7,9,10,4,8};
The radix is 13. The most significant digit is on the left. So the
actual value of this number is calculable as:
1*(13^0) + 5*(13^1) + 12*(13^2) + 7*(13^3) + 9*(13^4) + 10*(13^5) +
4*(13^6) + 8(13^7)
I'm stuck with this format, I can't change it. As parameters to my
function, I get the radix, the digit array, and a pointer to the last
digit. So altogether its:
struct Number {
unsigned radix;
unsigned *p_flast_digit;
unsigned digits[N];
};
OK now so what I want to do is divide this number by a particular
divisor. The divisor is held in a normal integer type (not as a string
of digits). Of course in order to perform this calculation, I could
simply use the expression I show above to convert the digit string to
a fully-fledge integer type, but I can't do that because the number is
*ridiculously* big, bigger than can be stored in a 64-Bit number.
So I got out a pen and paper and thought about ways of achieving this.
I ended up writing out a long-division sum by hand and then analysing
the steps I made to calculate it. I then started coding my method.
So basically it works as follows:
* I have a pointer to the most significant digit (which is at the end
of the string of digits). Let's call this pointer simply "p".
* I have an integer variable that holds a "sum of digits", and it
starts off as zero. What happens is I add "*p" to the sum_of_digits,
and then I decrement "p". I keep doing this in a loop until
sum_of_digits becomes greater than or equal to divisor, so the loop
would be:
unsigned sum_of_digits = 0;
for (;
{
sum_of_digits += *p;
if (sum_of_digits >= divisor) break;
--p;
}
(Of course I need to make allowances for running out of digits but
bear with me)
* When sum_of_digits becomes greater than or equal to the divisor, I
perform a division (i.e. sum_of_digits / divisor).
* I take the result of this division and I use it as the most
significant digit of the result. Then I take the remainder and I
prefix it to the original number replacing the digits I've just
divided into (exactly how you'd do it with a pen and paper). Then I
start again, dividing the divisor into this new number, taking down
extra digits as I need them. The result I get from the second division
is used as the second most significant digit of the result. Perform
another division, I get the third most significant digit, and so on.
Is my pen-and-paper approach a bit ridiculous, or is it a good way of
going about this?