Расчет BigDecimal результатов в неточном ответе - PullRequest
0 голосов
/ 06 сентября 2018

Так что я просто хотел пошевелиться, чтобы посмотреть, смогу ли я сделать это, чтобы я мог вычислить E, но вместо этого иметь его, чтобы у меня были динамические степени точности. Хотя я и сделал это технически, независимо от того, что я вставил в переменную PRECISION, последние несколько чисел всегда отличаются от того, что предполагается фактическим значением E. Я не совсем уверен, почему, но помощь будет оценена.

import java.math.BigDecimal; //To use for calculating E

public class ComputeE {
    public static double calcDenominator(int n)
    {
        double denominator = 1.0;   //Start the BigInt with 1
        for(int i = 1; i < n; i++) // Run n-1 amount of times
        {
            denominator = denominator * i;   // Multiply BigInteger by the BigInteger obtained with the int value i
        }
        return denominator;

    }


    public static void main(String[] args) {


        BigDecimal e = new BigDecimal(0.0);
        int PRECISION = 15;
        int iterations = 0;
        for(int i = 0; i < PRECISION; i++)
        {
            iterations++;
            BigDecimal numerator = new BigDecimal(1.0); // to divide, we need two BigDecimals, the numerator is 1
            BigDecimal factorial = new BigDecimal(calcDenominator(i));  // the denominator is i! which we get from calling the factorial method
            factorial = numerator.divide(factorial, PRECISION, BigDecimal.ROUND_UNNECESSARY);  // compute 1/i!, note divide is overloaded, this version is used to
                                                                  //     ensure a limit to the iterations when division is limitless like 1/3
            e = e.add(factorial);                   // add the latest 1/i! to e

        }



        System.out.println("Computed value of e : " + e);
        System.out.println("Expected value of e : " + Math.E);

    }
}

1 Ответ

0 голосов
/ 06 сентября 2018
  1. Округление необходимо здесь необходимо. Используйте что-то вроде HALF_EVEN. Более того, используйте значение enum RoundingMode.HALF_EVEN, поскольку целочисленные константы для режима округления устарели.

  2. В calcDenominator измените условие цикла for на i <= n, иначе вы добавите 1 слишком много раз в main и получите значение 1 слишком высоко.

  3. Вы можете использовать BigDecimal.ONE для инициализации numerator. Это не влияет на результат, но зачем создавать ненужный объект? Тот же комментарий по инициализации e, за исключением BigDecimal.ZERO.

  4. Вы используете первые PRECISION члены бесконечной серии (серии Маклаурина), которая приближается к e , иррациональному числу. Когда вы обрезаете цикл for, возникает ошибка, которая математически ожидается. С учетом вышеуказанных изменений и увеличения PRECISION до 50 я получаю следующее, что выглядит достаточно точно.

Computed value of e : 2.71828182845904523536028747135266249775496954201584
Expected value of e : 2.718281828459045

Это точно, несмотря на использование конструктора double для BigDecimal, потому что значащие цифры для double начинаются с первого ненулевого бита, так что даже если вы вычисляете 1 / n! для больших n значащие цифры достаточно хороши для добавления к существующему приближению для e .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...