I'm trying to write a power function in c without calling pow().
double power (double X, int Y)
{
int i;
double value = 1;
for (i = 0; i < Y; i++)
value *= X;
return value;
}
My question is, is there any reason you can see that this function would not work properly with any given test values? I am trying to cover all input possibilities.
-Thanks
-
It will be quite slow and quite imprecise.R.. GitHub STOP HELPING ICE– R.. GitHub STOP HELPING ICE2013年10月21日 03:47:25 +00:00Commented Oct 21, 2013 at 3:47
-
I changed value to a double, thanksuser28374– user283742013年10月21日 04:18:47 +00:00Commented Oct 21, 2013 at 4:18
2 Answers 2
This function is inadequate for several reasons:
It's buggy. Notice that
value
is declared as anint
rather than adouble
, which means that if you try to computepower(1.5, 1)
, you'll get back 1 rather than1.5
. In fact, it will be wrong on almost all inputs.It doesn't handle negative exponents. Try computing
power(2, -1)
. The correct answer is0.5
, but your function (after fixing theint
bug noted above) will return 1 rather than0.5
. You can fix this pretty easily (you could, for example, computepower(2, 1)
and then take the reciprocal), but it's troublesome as currently written.It's slow. Most exponentiation, when the power is an integer, is computed using an algorithm called exponentiation by squaring , which is considerably faster than your code. Exponentiation by squaring will do Θ(log Y) multiplications, compared to the Θ(Y) multiplications your code makes. It will take exponentially longer for your function to complete.
It doesn't handle fractional exponents. Try computing
power(1.5, 1.5)
. You'll get the wrong answer because the exponent is anint
, not adouble
. Correcting this isn't easy; search around on Stack Overflow for other questions on how to implement this properly.It reinvents the wheel. At a fundamental level, you should ask yourself why you're rewriting a function provided to you by the language's math libraries. This can introduce bugs or inefficiencies into the program (see the earlier bullet points) and at the end of the day you haven't increased the functionality.
Hope this helps!
6 Comments
int
bug I mentioned in the first part. Once that's accounted for, I think the overflow issue will resolve.Your function should be like this, it will run slower than pow() which runs in O(log Y):
#include<math.h>
#define ABS(x) ((x<0)?(-x):(x))
double power (double X, int Y)
{
int i;
double value = 1;
if (Y == 0)
{
return 1.0;
}
else if (X == 0)
{
return 0.0;
}
for (i = 0; i < ABS(Y); i++)
{
value *= X;
if (value == NAN
|| value == INFINITY
|| (X > 0 && (value*X) < value)
|| (X < 0 && (value*X) > value))
{
return NAN;
}
}
if (Y < 0) return (1.0/value);
else return value;
}