Почему я получаю этот результат в своем собственном коде для n-го корня? - PullRequest
0 голосов
/ 04 сентября 2018

Я пытаюсь сделать свой собственный код для вычисления n-го корня числа. Он отлично работает для чисел порядка 10 9 , но для больших чисел он дает мне странные вещи.

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;
    }
}

Где power() - это функция, которую я написал:

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;
}

Дело в том, что если сделать nroot(2, 10000000000) /* 10.000.000.000 */ я получу -1.000002.

Я не понимаю, откуда этот результат, потому что если я получу nroot(2, 1000000000) /* 1.000.000.000 */, я получу 31622.776599, что является правильным результатом.

Любой отзыв будет оценен.

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Ваш код имеет неопределенное поведение, потому что xf неинициализирован в while (xf < (int)b) {.

В некоторых случаях это работает только случайно ... Более того, приведение b к (int) не нужно и контрпродуктивно, если b больше INT_MAX, около 2 миллиардов в 32-битных системах. Обратите внимание, что i также неинициализирован. Вы, вероятно, должны установить для i и xf значение 1 перед этим циклом:

i = xf = 1;    
while (xf < b) {
    i++;
    xf = power(i, a);
}
0 голосов
/ 04 сентября 2018

Ваша power функция выглядит нормально.

Ваша проблема исходит из этой строки:

while(xf<(int)b)

Вы приводите b к целому числу, по умолчанию 32 бита, максимальное значение которого равно 2e9 (см. INT_MAX).

Таким образом, когда b больше INT_MAX, ваш код больше не работает.

Чтобы исправить проблему, просто удалите приведение, код становится:

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