user1262876
user1262876

Reputation: 31

c++ or c pow giving wrong result

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

Answers (5)

torrential coding
torrential coding

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

Pavan Manjunath
Pavan Manjunath

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

Shashank Kadne
Shashank Kadne

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

MD Sayem Ahmed
MD Sayem Ahmed

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

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

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

Related Questions