Alberto Navarro
Alberto Navarro

Reputation: 31

Why I get this result in my own code for the nth root?

I'm trying to do my own code to calculate the nth root of a number. It works fine for numbers in the order of magnitude of 109, but for bigger numbers it gives me weird things.

double nroot(double a, double b) {
    int j;
    double i, wtemp, w, xf, x, bgint, lsint, eps = 0.000000001, delta;

    if (b == 0)
        return 0;
    if (a == 1)
        return b;
    while (xf < (int)b) {
        i++;
        xf = power(i, a);
    }
    if (xf == b)
        return i;
    if (xf == b && a < 0)
        return 1 / i;   
    else {
        bgint = i;
        lsint = i - 1;      
        for (j = 0; j < 1000000; j++) { 
            x = ((b - power(lsint, ABS(a))) / (xf - power(lsint, ABS(a)))) * (bgint - lsint);   
            w = lsint + x;
            delta = w - wtemp;
            if (ABS(delta) < eps) {
                return w;
            } else {    
                lsint += x;
                wtemp = w;              
            }
        }
        if (a > 0)
            return w;
        else
            return 1 / w;
    }
}

Where power() is a function I wrote:

double power(double a, double b) {
    int countPower;
    double result;
    if (b >= 0) {
        for (result = 1, countPower = 0; countPower < (int)b; countPower++)                 
            result *= a;
    } else {
        for (result = 1, countPower = (int)-b; countPower > 0; countPower--)                    
            result /= a;
    }
    return result;
}

The thing is this: If a do nroot(2, 10000000000) /* 10.000.000.000 */ I get -1.000002.

I don't understand where does this result come from because if I do nroot(2, 1000000000) /* 1.000.000.000 */ I get 31622.776599, which is the correct result.

Any review will be appreciated.

Upvotes: 1

Views: 85

Answers (2)

chqrlie
chqrlie

Reputation: 144550

Your code has undefined behavior because xf is uninitialized in while (xf < (int)b) {.

It works only by chance in some cases... Furthermore, casting b as (int) is unnecessary and counterproductive if b is larger than INT_MAX, around 2 billion on 32-bit systems. Note that i is uninitialized as well. You should probably set both i and xf to 1 before this loop:

i = xf = 1;    
while (xf < b) {
    i++;
    xf = power(i, a);
}

Upvotes: 3

Mathieu
Mathieu

Reputation: 9619

Your power function seem ok.

Your problem comes from this line:

while(xf<(int)b)

You cast b to an integer, certainly 32 bits by default, which maximum value is about 2e9 (see INT_MAX).

So when b is over INT_MAX, your code do no longer work.

To correct the problem, just remove the cast, the code becomes:

while (xf < b)
{ 
    i++;
    xf = power(i, a);
}

Upvotes: 2

Related Questions