Ряд Тейлора - вычисление sin(x) с точностью до 6 цифр

Я должен вычислить sin(x) с помощью ряда Тейлора, пока на выходе не будет 6 знаков после запятой. Аргумент - это угол. Я не реализовывал проверку десятичных разрядов, я просто печатал следующие значения (чтобы проверить, работает ли он), но после 10-20 итераций он показывает бесконечность /NaN.

Что не так в моем мышлении?

public static void sin(double x){
    double sin = 0;
    int n=1;
    while(1<2){

        sin += (Math.pow(-1,n) / factorial(2*n+1)) * Math.pow(x, 2*n+1);
        n++;

        try {
            Thread.sleep(50);
        } catch (InterruptedException ex) {

        }

        // CHECKING THE PRECISION HERE LATER
        System.out.println(sin);
    }
}

уравнение:

введите описание изображения здесь

3 ответа

Решение

Не вычисляйте каждый термин, используя факториалы и полномочия! Вы будете быстро переполнены. Просто поймите, что каждый следующий член равен -term * x * x / ((n+1)*(n+2)), где n увеличивается на 2 для каждого члена:

double tolerance = 0.0000007; // or whatever limit you want
double sin = 0.;
int n = 1;
double term = x;
while ( Math.abs(term) > tolerance ) {
  sin += term;
  term *= -( (x/(n+1)) * (x/(n+2)) );
  n+= 2;
}

Чтобы добавить ответ, предоставленный @Xoce (и @FredK), помните, что вы вычисляете ряд Маклаурина (особый случай Тейлора о x = 0). Хотя это будет довольно быстро сходиться для значений, которые находятся в пределах pi/2 нуля, вы не можете получить сходимость цифр, прежде чем факториал взрывается для значений x дальше, чем это.

Я рекомендую использовать фактическую серию Тейлора о ближайшем значении sin(x) для которого известно точное значение (т. е. ближайший кратный pi/2не только около нуля. И обязательно сделайте проверку сходимости!

Проблема:

Ошибка NAN обычно является действительно большим числом, что может произойти, если вы разделите 2 числа, но делитель очень маленький или равен нулю.

Решение

Это происходит потому, что ваше факториальное число становится переполненным, и позже в какой-то момент вы снова делитесь на ноль, если ваш факториал принимается в качестве аргумента int, то измените его, например, на BIgInterger объект.

Другие вопросы по тегам