69 lines
1.6 KiB
C++
69 lines
1.6 KiB
C++
#include "cheapgmp.hpp"
|
|
|
|
using namespace std;
|
|
|
|
namespace cheapgmp {
|
|
namespace {
|
|
|
|
/* Given a list representing a decimal number as a multiplicand,
|
|
multiply each digit by a multiplier, leaving in its place the
|
|
remainder modulo 10 of the result, and using result diviso 10
|
|
as a carryover to the 10^(n+1) slot */
|
|
|
|
void multiply(gmrep &multiplicand, ulong multiplier) {
|
|
gmrep res(new lmrep());
|
|
ulong rem = 0;
|
|
for_each(multiplicand->rbegin(), multiplicand->rend(), [&rem, by](ulong &i) {
|
|
ulong t = (i * multiplier) + rem ;
|
|
i = t % 10 ;
|
|
rem = t / 10;
|
|
});
|
|
|
|
/* When out of list elements, drain the result diviso 10 until
|
|
the new result is complete */
|
|
|
|
while(rem > 0) {
|
|
in->push_front(rem % 10);
|
|
rem = rem / 10;
|
|
}
|
|
}
|
|
|
|
/* Given an integer, return a std::list<int> in which each node
|
|
represents a decimal placement, i.e the end() is the ones,
|
|
end().prev() is the tens, etc. */
|
|
|
|
gmrep makerep(const ulong in) {
|
|
gmrep res(new lmrep());
|
|
if (in == 0) {
|
|
res->push_front(0);
|
|
return res;
|
|
}
|
|
|
|
ulong rem = in;
|
|
while(rem > 0) {
|
|
res->push_front(rem % 10);
|
|
rem = rem / 10;
|
|
}
|
|
return res;
|
|
}
|
|
}
|
|
|
|
/* Perform the operation multiple times, to produce an exponential
|
|
result */
|
|
|
|
gmrep makepower(const ulong base, const ulong power) {
|
|
if (power == 0) {
|
|
return makerep(base == 0 ? 0 : 1);
|
|
}
|
|
|
|
gmrep res = makerep(base);
|
|
ulong ct = power;
|
|
while(ct > 1) {
|
|
multiply(res, base);
|
|
ct--;
|
|
}
|
|
return res;
|
|
}
|
|
}
|
|
|