Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why main function do not recognise if another function return float type number

Tags:

c++

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.

like image 623
mr_azad Avatar asked Aug 22 '26 05:08

mr_azad


1 Answers

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.

like image 97
Willem Van Onsem Avatar answered Aug 24 '26 20:08

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!