2

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

Puppy
  • 144,682
  • 38
  • 256
  • 465
user1262876
  • 31
  • 1
  • 7

5 Answers5

6

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.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
4

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.

Pavan Manjunath
  • 27,404
  • 12
  • 99
  • 125
  • @user1262876 I agree taylor's expansion is laborious to implement in C/C++. I am working here. Will edit my answer as soon as I find something – Pavan Manjunath Mar 20 '12 at 06:42
  • i did: inline double log(double x) { return x*(1.0 - x*(0.5 - x*(1.0/3.0 - x*(0.25 - x*(0.2 - x/6.0))))); } but it still give wrong, and the pow dosent output the right value... – user1262876 Mar 20 '12 at 14:07
  • You are calculating only till 6 terms. And also, by eyesight, it looks very probable that your equation might have gone wrong. Use a loop as I've done for the exp() function – Pavan Manjunath Mar 20 '12 at 14:40
  • Pavan Manjunath, please don't misunderstand me in any wrong way, but could you do the last part, so i can learn from it, you look like a smart man with skills. google says 2^3.2 = 9.18958684, but when i try the pow_x you made it, it says: 2^3.2 = 8 – user1262876 Mar 21 '12 at 00:06
0

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.

Community
  • 1
  • 1
MD Sayem Ahmed
  • 28,628
  • 27
  • 111
  • 178
  • Still wont work! When the powers are floating point numbers, exponentiation cannot be so easily achieved using repeated multiplication – Pavan Manjunath Mar 20 '12 at 06:20
0
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
Shashank Kadne
  • 7,993
  • 6
  • 41
  • 54
0

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.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
torrential coding
  • 1,755
  • 2
  • 24
  • 34