-1
 #include<iostream>
 #include<cmath>
 using namespace std;
 int main()
 {
double x,y,z;
cin>>x>>y;
z=exp(y*log(x));
cout<<z;
system("pause");
return 0;
}

this is code to find power of a numbers whose exponent is floating point number i.e 2.3^2.3 if we do using logs and antilogs we can get the answer easily but my interview question was to find power with out using any math library in c++. i googled it and did not able to understand some of the refere nces from google.

unwind
  • 391,730
  • 64
  • 469
  • 606
Rajesh M
  • 634
  • 11
  • 31
  • This is not C, I removed the tag. – unwind Mar 22 '13 at 13:37
  • 1
    I was expecting this question to mention some of the stuff you didn't understand so you could get an explanation. – Benjamin Bannier Mar 22 '13 at 13:39
  • @unwind, while the question bears some C++ accoutrements, the substance of the question is C friendly. The cin/cout could easily be changed to scanf/printf without affecting the gist of the question. – metal Mar 22 '13 at 13:40
  • @rafa nadal, Even easier than your log/exp line is pow(x,y). What exactly are you trying to calculate without using standard functions -- z, given x and y? – metal Mar 22 '13 at 13:44
  • @metal "without using any math library" <= I don't think that `pow(x,y)` qualifies. – us2012 Mar 22 '13 at 13:45
  • @us2012, right. I was just noting that there was a less complicated way to ask the same question with standard functions since exp(y*log(x)) == pow(x,y). – metal Mar 22 '13 at 13:48
  • From what you've told us, it's hard to say what the interviewer was looking for, but I'd guess they wanted to hear that you know about approximations to `log`/`exp` and how they are needed to implement these instructions in hardware. – us2012 Mar 22 '13 at 13:50

2 Answers2

2

You can always implement exp() and log() yourself.

And it's easier to actually implement 2x and log2x for the purpose and use in the same way as exp() and log().

2x = 2integer_part(x)+fractional_part(x) = 2integer_part(x) * 2fractional_part(x)

2fractional_part(x) can be calculated for -1 <= x <= +1 using Taylor series expansion.

And then multiplying by 2integer_part(x) amounts to adjusting the exponent part of the floating point number by integer_part(x) or you can indeed raise 2 to the integer power of integer_part(x) and multiply by that.

Similarly, log2x = log2(x * 2N) - N

where N (an integer, a power of 2) is chosen such that 0.5 <= x * 2N <= 1 (or, alternatively, between 1 and 2).

After choosing N, again, we can use Taylor series expansion to calculate log2(x * 2N).

And that's all, just a little bit of math.

EDIT: It's also possible to use approximating polynomials instead of Taylor series, they are more efficient. Thanks Eric Postpischil for reminding. But you'd probably need a math reference to find or construct those.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • Taylor series are generally not used for this sort of function evaluation. Engineered minimax polynomials are better. Taylor series take too many terms to converge and have error problems away from their centers. Taylor series are featured in calculus class for explaining concepts and defining properties, but they are generally not useful for numerical work. – Eric Postpischil Mar 22 '13 at 15:52
  • @EricPostpischil I don't remember abut exp(x), but when I coded log(x) for a library a better convergence was achieved by calculating some polynomial of (x-1)/(x+1). So, yeah, that can be done as well, but for the purpose of explaining this stuff Taylor is enough. – Alexey Frunze Mar 22 '13 at 15:59
  • I understand not wanting to go into the details of minimax polynomials. However, to avoid misleading people, I might replace “Taylor series expansion” with “a prepared polynomial that approximates the function”. – Eric Postpischil Mar 22 '13 at 16:07
0

You could use Taylor series expansions for ln(x) and e^x:

ln(x) = 2 * sum[ ((x-1)/(x+1))^(2n-1) / (2n-1), n=1..inf ]
      = 2 [ (x-1)/(x+1) + (1/3)( (x-1)/(x+1) )^3 + (1/5)( (x-1)/(x+1) )^5 + (1/7) ( (x-1)/(x+1) )^7 + ... ] 
e^x = sum(  x^n / n!, n = 0 .. inf ) 
    = 1/1 + x/1 + x^2 / 2 + x^3 / 6 + ...

Where you could implement the integral powers as a for-loop and continue the expansion for the desired approximation. Then plug in your values, and badda-bing, badda-boom. Note the convergence regions for the above are for x > 0 for ln(x) and for all values for e^x.

metal
  • 6,202
  • 1
  • 34
  • 49
  • Taylor series are generally not used for this sort of function evaluation. Engineered minimax polynomials are better. Taylor series take too many terms to converge and have error problems away from their centers. Taylor series are featured in calculus class for explaining concepts and defining properties, but they are generally not useful for numerical work. – Eric Postpischil Mar 22 '13 at 15:53
  • True, but this is an interview question. I presume they wouldn't be too picky. – metal Mar 22 '13 at 17:13