Вычисление e^x было в порядке. Но не грех х

Я совсем новичок в кодировании. И я знаю, что этот код также выглядит не очень хорошо спроектированным. Если я не должен задавать такие вопросы, пожалуйста, дайте мне знать. Сниму и разберусь сам (надеюсь).

Моя первая программа, которая вычисляла ex с помощью ряда Тейлора, работала хорошо:

#include <stdio.h>
#include <math.h>

double calculateTaylorSeries(double x, int n) {
    double result = 1.0; // The first term in the series

    double term = 1.0;
    for (int i = 1; i <= n; i++) {
        term *= x / i; 
        result += term; 
    }

    return result;
}

int main(void) {
    double x;

    printf("Enter the value of x: ");
    scanf("%lf", &x);

    int n;
    printf("Enter the number of terms (n): ");
    scanf("%d", &n);

    double taylorApproximation = calculateTaylorSeries(x, n);

    printf("e^%.2lf (approximated using %d terms): %lf\n", x, n, taylorApproximation);

    return 0;
}

Но сделать то же самое с функцией sin казалось трудным. Так как есть чередующийся термин аспект. И мощность и знаменатель должны быть нечетными.

Моя логика кажется мне прекрасной. Но это дает мне неточные результаты.

#include <stdio.h>
#include <math.h>

double calculateTaylorSeries(double x, int n)
{
    double result = x;
    double term = 1.0;
    int sign = -1;
    for (int i = 1; i <= 2 * n; i++)
    {
        if (i % 2 == 1)
        {
            term *= x / i * sign; //term = term * x/i * sign;

            result += term; // result = result + term;
        }
    }

    return result; 
}

int main(void)
{
    double x; 
    printf(" Enter the angle : ");

    scanf("%lf", &x);
    
    int n;
    
    printf("Enter the number of terms(n):");
    scanf("%d", &n);

    double sinX = calculateTaylorSeries(x, n);

    printf("sin(%lf) = %lf", x, sinX);

    return 0;
}

Вот результат:

Enter the angle : 6.28
Enter the number of terms(n):2
sin(6.280000) = 13.146133
Enter the angle : 234
Enter the number of terms(n):15 
sin(234.000000) = -49592774856964366336.000000

И я также смущен, почему, когда я запускаю это в коде VS, он показывает мне эту ошибку:

The preLaunchTask 'C/C++:gcc.exe build active file' terminated with exit code -1.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
53
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы не меняете sign и в цикле считаете только пропускаете четные итерации.

Пример рабочего кода:

double fact(unsigned n)
{
    double result = 1;
    do
    {
        result *= n;
    }
    while(--n);
    return result;
}

double msin(double x, unsigned n)
{
    double result = x;
    for(unsigned i = 0; i < n; i++ )
    {
        result += (i % 2 ? 1 : -1) * pow(x, 3 + 2 * i) / fact(3 + 2 * i);
    }
    return result;
}

int main(void)
{
    for(unsigned n = 2; n < 10; n++)
        printf("%.30f\n%.30f\n\n", msin(1.4, n), sin(1.4));
}

n - количество итераций.

https://godbolt.org/z/s3b3bEshW

Я не знал, что вы можете сделать это. Большое спасибо! Но что я сделал не так?

Rian Rahman 05.08.2023 19:55

к сожалению нет. Но, вероятно, потому, что я не могу следовать синтаксису.

Rian Rahman 05.08.2023 19:59
Ответ принят как подходящий

В вашем расчете срока есть 2 ошибки:

  • ты не меняешь знак
  • вы пропускаете четные множители в вычислении термина. Вы должны только пропустить их в суммировании.

Вот модифицированная версия:

#include <stdio.h>
#include <math.h>

double calculateTaylorSeries(double x, int n) {
    double result = x;
    double term = 1.0;

    for (int i = 1; i <= 2 * n; i++) {
        term *= x / i;
        if (i % 2 == 1) {
            term = -term;
            result += term; // result = result + term;
        }
    }
    return result; 
}

int main(void) {
    double x; 
    printf("Enter the angle in radians: ");
    if (scanf("%lf", &x) != 1)
        return 1;
    
    int n;
    printf("Enter the number of terms(n):");
    if (scanf("%d", &n) != 1)
        return 1;

    double sinX = calculateTaylorSeries(x, n);
    printf("sin(%lf) = %lf", x, sinX);
    return 0;
}

Понятно! Спасибо.

Rian Rahman 05.08.2023 20:06

Мне понравилось, как этот ответ сохраняет оригинальный способ работы OP с термином, который совсем не был похож на новичка!

Weather Vane 05.08.2023 20:19

Да, и это также действительно здорово узнать что-то подобное, вместо того, чтобы изучать это по видео на YouTube.

Rian Rahman 05.08.2023 21:25

Проблемы опубликованного кода уже упоминались в ответе chqrlie.

Обратите внимание, что есть способ «пропустить» четные индексы, если учитываются их коэффициенты:

// six(x) = x - x^3/3! + x^5/5! - x^7/7!* + ...
//        = x + x*(-x^2)/(2*3) + x*(-x^2)*(-x^2)/(2*3 * 4*5) + ...
double sin_Taylor(double x, int n)
{
    double result = x;

    double x2 = - x * x;
    double term = x;
    
    for ( int i = 0; i < n; ++i )
    {
        term *= x2 / (((i + 1) * 2) * (i * 2 + 3)); 
        result += term; 
    }

    return result; 
}

В прямом эфире, здесь: https://godbolt.org/z/K33z4ebdz

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