Reputation: 31
im trying make my own pow, but i'm getting wrong result
im getting : 2^3.3 = 16, which is wrong... why?
#include <iostream>
using namespace std;
double new_pow(double base, double power){
double result = 1;
for(int i = 0; i <= power; i++) {
result *= base;
}
return result;
}
int main (int argc, char * const argv[]) {
std::cout << new_pow(2,3.3) << endl;
return 0;
}
Please help me find the bug
Upvotes: 2
Views: 4022
Reputation: 1765
You are looping by treating power
as an int
. The loop will run 4 times and return 2^4 = 16
.
How to approximate decimal exponents using logarithms.
Upvotes: 0
Reputation: 28525
Ignacio's answer already mentions using logarithms. But we ultimately end up using exp()
which again is a library function. So if you don't want to use library functions at all, then you have to resort to something like Taylor's expansion of x^y
As direct evaluation of Taylor's expansion for x^y
is tedious, as Ignacio mentioned, base^power = exp( power*ln(base) )
. And taylor's expansion for e^x is quite simple and that for ln(x) is also very simple. Both of them yield for simple interative/recursive implementation in C
Here is a simple implementation of e^x
using the above Taylor's expansion
double pow_x ( double x , unsigned i )
{
double prod=1;
if ( i == 0 )
return 1;
while ( i )
{
prod*=x;
i--;
}
return prod;
}
long long factorial ( unsigned n )
{
if ( n == 0 )
return 1;
return n * factorial (n-1);
}
// Function to calculate e^x. Hence expo(5, 20) is calculating
// e^5 by summing 20 terms from the infinite series expansion
// and NOT a power calculation of 5^20
double expo ( double x, int terms )
{
/* terms tells us how long should we expand the taylor's series */
double sum=0;
unsigned i=0;
while ( i< terms )
{
sum+= pow_x(x,i)/factorial(i);
i++;
}
return sum;
}
exp(5.93,20)
gives 376.152869
which Google tends to agree.
I hope, using this example, you can implement ln(x)
on your own.
Upvotes: 4
Reputation: 8101
for(int i = 0; i <= power; i++)
should be
for(int i = 1; i <= power; i++)
Otherwise, it will run for one extra iteration.
As mentioned in Ignacio Vazquez-Abram's answer. Assume you want the power y = x^b. That is equivalent to ln(y) = b*ln(x).
so y = exp(b*ln(x))
y = Math.e(b*Math.Log(x)) //Java
Upvotes: 0
Reputation: 29166
Because you are incrementing i
by 1. so after 4.0
, it will be directly incremented to 5.0
, thus making the condition check of the loop false, and thus terminating the loop.
Also, your starting value for the loop variable is 0
, so you should check it like this -
for(double i=0; i<power; i++)
You can take a look at this answer to get an idea about how to implement floating point exponentiation and here for a pretty high level implementation of it.
Upvotes: 0
Reputation: 798446
The bug is that your loop runs 4 times, since it won't be more than 3.3 for 4 iterations. This is why floating point exponentiation is implemented with logarithms, not repeated multiplication.
Upvotes: 6