Code: Select all
int pow(int base, int exp)
{
int res = base;
if(exp == 0)
return 1;
if(exp == 1)
return base;
for (; exp-1 > 0; exp--) {
res *= base;
}
return res;
}
Code: Select all
int pow(int base, int exp)
{
int res = base;
if(exp == 0)
return 1;
if(exp == 1)
return base;
for (; exp-1 > 0; exp--) {
res *= base;
}
return res;
}
Code: Select all
double pow(double base, int exp)
{
double res = 1;
while(exp--)
res *= base;
return res;
}
Code: Select all
#define reciprocal(n) (1 / (n))
#define odd(x) ((x) % 2)
#define even(x) (!odd(x))
double pow(double base, int exp)
{
double accumulate = 1.0;
if (0.0 == base) // sanity check - is base zero? 0^exp == 0
{
return 0.0;
}
else if (1 == base) // sanity check - is base one? 1^exp == 1
{
return 1.0;
}
else if (0 == exp) // sanity check - is exp zero? base^0 == 1
{
return 1.0;
}
else if (0 > exp) // base^(-exp) == 1 / base^exp
{
return reciprocal(pow(base, abs(exp)));
}
else
while (0 < exp)
{
if (even(exp))
// by halving even exponents and squaring the base,
// the number of multiplications needed is reduced
// turning the algorithm from O(n) time and O(1) space
// to 0(log n) for time while remaining O(1) for space.
{
exp /= 2;
base *= base;
}
else
{
// For odd numbers, multiply the base by base^(exp-1)
// Since exp - 1 is guaranteed to be even, it will then
// use the halving formula above to reduce the total
// number of multiplications.
accumulate *= base;
exp--;
}
}
return accumulate;
}
Code: Select all
exp /= 2
Code: Select all
exp>>=1
One question: Where does the "abs" come from? I didn't notice it beforeSchol-R-LEA wrote:Code: Select all
return reciprocal(pow(base, abs(exp)));
I knew I'd missed something. Actually, it might be more than one cycle, and even if it is only one, well, they do add up...df wrote: since exp is an integer
replacewithCode: Select all
exp /= 2
might save you _1_ cycle heheCode: Select all
exp>>=1
Code: Select all
double pow(double base, int expt)
{
return exp((expt * log(base));
}
Oops. It's exactly the kind of math.h function were supposed to be implementing here, isn't it? OK, then here's a quick and dirty version that should do:chris wrote:One question: Where does the "abs" come from? I didn't notice it beforeSchol-R-LEA wrote:Code: Select all
return reciprocal(pow(base, abs(exp)));
Code: Select all
#define abs(x) (0 < (x)) ? (x) : (-x))
Code: Select all
double pow(double base, int expt)
{
if(expt == 0)
return 1;
else
return base * pow(base, expt - 1);
}
Certainly; this is one of the simplest ways to implement this. There's no reason for it not to be multithread friendly; it's a basic recursive function, with no shared memory state. If you think about it, you'd see that has to be at least serially reentrant, or the recursion wouldn't work properly.Pete wrote: I've seen it implemented before something like this (off the top of my head)
With the claim that its multithreaded friendly?Code: Select all
double pow(double base, int expt) { if(expt == 0) return 1; else return base * pow(base, expt - 1); }
Code: Select all
double pow(double base, int expt)
{
if(expt == 0)
return 1;
else if (expt == 1)
return base;
else if (even(base))
{
base = pow(base, (expt / 2));
return base * base;
}
else
return base * pow(base, expt - 1);
}