I am give 2 and -2 as input and suppose to get 0.25 as output. But the result I am getting is 1.
#include<iostream>
using namespace std;
float power(float x, float y);
int main()
{
float x=0, y=0;
cin>>x>>y;
cout<<power(x, y)<<endl;
return 0;
}
float power(float x, float y)
{
float c;
if (y == 0) return 1;
c=x*power(x, (y+1));
return (1/c);
}
If I return c; instead of return 1/c; and in the main function put cout<<1/power(x, y); I am getting the right result. Any one please can suggest a reason behind this it would be helpful for me. Thank you in advance.
The reason you are getting the wrong result, is that in your recursive call, you constantly invert the result:
float power(float x, float y) {
float c;
cout << y << endl;
if (y == 0) return 1;
c=x*power(x, (y+1)); //result previous call (can already been inversed)
return (1/c); //the inversion step
}
What thus happens is:
pow(2,-2)
pow(2,-1)
pow(2,0) = 1
return 1/(2*1)=0.5
return 1/(2*0.5)=1 (here you undo the effect)
I've omitted the calculations in between, because these are not "relevant" to show what is wrong. Or a more advanced example:
pow(2,-4)
pow(2,-3)
pow(2,-2)
pow(2,-1)
pow(2,0) = 1
return 1/(2*1)=0.5
return 1/(2*0.5)=1 (here you undo the effect)
return 1/(2*1)=0.5
return 1/(2*0.5)=1 (here you undo the effect)
Thus you multiply by x and divide by x. If the original y is even, it will always result in 1.00, otherwise it will result in 1/x. Furthermore this method will never end if you provide a positive exponent.
If you don't invert constantly, it will (in the case of a negative y), simply calculate x^-y, so you can do the inversion post-call.
But your method is in general rather error-prone: performing increment/decrement on floats as well as checking on zero is known to ask for trouble. Furthermore your algorithm isn't very efficient. A better way to solve this (with integral power), is:
float power(float x, int y) {
if(y < 0) {
return 1.0f/power_positive(x,-y);
} else {
return power_positive(x,y);
}
}
float power_positive(float x, int y) {
if(y == 0) {
return 1.0f;
}
float r = power_positive(x*x,y>>0x01);
if(y&0x01) {
r *= x;
}
return r;
}
This algorithm will work faster as well since it divides the exponent by half each time. As said before, it however works only for integral exponents. You can generalize it. But I would trust the 80x87-coprocessor more with floating point arithmetic anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With