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.

+3


source to share


1 answer


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.

+1


source







All Articles