Why does the main function not recognize if another function returns float type
I am giving 2 and -2 as input and should 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 return 1/c;
and in the main function put cout<<1/power(x, y);
, I get the correct result. Any of them can suggest a reason for this, it would be helpful to me. Thank you in advance.
source to share
The reason you are getting the wrong result is because when you call recursively, you are constantly inverting 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's happening:
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 skipped the calculations in between because they 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)
So you are multiplying by x
and dividing by x
. If the original is y
even it will always matter 1.00
, otherwise it will result in 1/x
. Also, this method will never end if you provide a positive indicator.
If you don't invert constantly it will be (in case of negative y
), just compute x^-y
so you can do the inverse callback.
But your method as a whole is more error prone: doing increment / decrement on floats and also checking for zero is notoriously difficult. Also, your algorithm is not very efficient. The best way to solve this problem (with built-in power):
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 run faster as it halves the metric each time. As stated earlier, however, it only works for integral indicators. You can generalize it. But I would still trust an 80x87 coprocessor with floating point arithmetic.
source to share