Использование ряда Тейлора для нахождения sin(x) в C

У меня есть задание, в котором мой профессор хочет, чтобы мы вычислили sin(x), используя ряд Тейлора. Он хочет, чтобы мы остановили итерации, когда разница между двумя последовательными дробями меньше 10^-6.

В итоге я подошел к проблеме, сказав, что, например, x ^ 5/5! совпадает с (x^3/3!) * (x^2/4*5) и что это верно для всех дробей. Поэтому я могу просто сохранить предыдущую рассчитанную долю и использовать ее на следующей итерации. Проблема в том, что число, которое я получаю, немного отличается от его фактического греха, и я не могу понять, почему. Заранее спасибо. Вот мой код:

#include <stdio.h>
#include <Math.h>
#define pi 3.14159265358979323846

int main(int argc, int **argv){
    
    int sign = -1, pwr = 3;
    double previous, current, rad,sum, degr;
    printf("Calculating sin using Taylor Series\n\n");
    printf("Give degrees: ");
    scanf("%lf", &degr);
    
    // translate to rads
    rad = degr*(pi/180);
    
    sum = rad;
    previous = rad;
    do{
        current = (previous * pow(rad, 2))/(pwr* pwr-1);
        
        sum += sign*current;
        pwr += 2;
        sign *= -1;
    }
    while(abs(current - previous) > pow(10, -6));
    
    printf("The sin of %lf degrees is ", degr);
    printf("%.6f\n", sum);
    printf("%.6f", sin(rad));
    return 0;   
}

person spiroulis    schedule 07.12.2020    source источник
comment
Разве (pwr* pwr-1) не должно быть (pwr * (pwr-1)) ?   -  person Steve Friedl    schedule 08.12.2020
comment
ответ действительно изменился после того, как я это исправил, но все еще несколько не так. Я хочу, чтобы по крайней мере 6 десятичных знаков были идентичны функции sin(x), но в лучшем случае я получаю 2. :(   -  person spiroulis    schedule 08.12.2020
comment
Вы хотели установить previous = current где-то в цикле? Если перед циклом вы измените previous = rad; на current = rad;, это может быть первая инструкция в цикле.   -  person Weather Vane    schedule 08.12.2020
comment
@WeatherVane omg, вы абсолютно правы, я забыл добавить это в цикл. Но даже после исправления это все еще не работает, может быть, мне следует посчитать это по-другому?   -  person spiroulis    schedule 08.12.2020
comment
Хорошо, но, пожалуйста, не обновляйте код в реальном времени. Вопрос должен оставаться в том виде, в каком он был задан (если только он не был опубликован достаточно хорошо или не был отредактирован для ясности).   -  person Weather Vane    schedule 08.12.2020
comment
извините, это был буквально мой первый пост здесь :)   -  person spiroulis    schedule 08.12.2020


Ответы (1)


Вы используете функцию abs, которая ожидает int и возвращает int. Это приводит к тому, что петля существует, если разница между текущим и предыдущим термином меньше 1, поскольку она установит diff в 0.

Вместо этого вам нужен fabs, который ожидает и возвращает double.

person dbush    schedule 07.12.2020
comment
о боже, большое спасибо, это решило это: D - person spiroulis; 08.12.2020