Функция, возвращающая NaN - PullRequest
0 голосов
/ 15 марта 2012

Я создал программу, которая вычисляет этот алгоритм, начиная с k = 1 и заканчивая его k = 100:

formula

Вот код, который я создал:

public static void calculatePi() {
    BigInteger firstFactorial;
    BigInteger secondFactorial;
    BigInteger firstMultiplication;
    BigInteger firstExponent;
    BigInteger secondExponent;
    int firstNumber = 1103;
    BigInteger firstAddition;
    double summationPi = 3.0;
    double currentPi = 3.0;
    double pi = 3.0;
    int secondNumber = 2;
    double thirdNumber = Math.sqrt(2.0);
    int fourthNumber = 9801;
    double prefix = 1;

    for(int i=1;i<101;i++){
        firstFactorial = factorial(4*i);
        secondFactorial = factorial(i);
        firstMultiplication = BigInteger.valueOf(26390*i);
        firstExponent = exponent(secondFactorial, 4);
        secondExponent = exponent(BigInteger.valueOf(396),4*i);
        firstAddition = BigInteger.valueOf(firstNumber).add(firstMultiplication);
        summationPi = firstFactorial.intValue()*firstAddition.intValue();
        summationPi /= firstExponent.intValue()*secondExponent.intValue();
        currentPi += summationPi;
    }

    prefix = secondNumber*thirdNumber;
    prefix = prefix/fourthNumber;

    summationPi = summationPi*prefix;

    pi = 1/summationPi;

    System.out.println("Pi is: " + pi);

    return;
}

Показатель функции (a, b);возвращает результат a ^ b.Функция factorial (a) возвращает факториал a.Я доказал, что обе эти функции работают отлично.Тем не менее, код, кажется, таинственным образом возвращает «NaN».Я понимаю, что это происходит, когда что-то делится на ноль, однако я не смог найти точку, в которой что-то делится на ноль.Есть ли что-нибудь еще, что могло бы вызвать это / я делаю неправильно?

Примечание: В операторе for я использую i как k в алгоритме.

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 15 марта 2012

Проблема:

Вероятно, в этих строках возникает ошибка:

summationPi = firstFactorial.intValue()*firstAddition.intValue();
summationPi /= firstExponent.intValue()*secondExponent.intValue();

Причина в том, что вы звоните intValue() на BigInteger, что не гарантируетсявернуть полное значение (поскольку int может содержать только 32 бита данных. Это также может сыграть с сохранением результата как double вместо BigDecimal).

Youзатем возьмите это возможное NaN значение и используйте его в качестве делителя в вашем делении.

Решение:

BigDecimal currentPi = BigDecimal.ONE;

currentPi = currentPi.add(
  new BigDecimal(firstFactorial.multiply(firstAddition))
    .divide(new BigDecimal(firstExponent.multiply(secondExponent)), new MathContext(10000)));

Обратите внимание, что я могу устранить summationPi путем объединения нескольких строк водин.Кроме того, MathContext, который появляется в методе divide(), установлен на 10000, это можно изменить с любой точностью, которую вы хотите.

Для получения дополнительной информации о проверке BigDecimal, API .

0 голосов
/ 16 марта 2012

Причина этой проблемы в этой строке:

summationPi / = firstExponent.intValue () * secondExponent.intValue ();

, где значение secondExponent становится таким большим, какя увеличиваю, что если вы получите значение int с помощью метода intValue (), вы получите 0.

...