Ряд Тейлора - вычисление 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
объект.