PAVAN KUMAR Ответов: 2

Оценка sinx с использованием бесконечных рядов


оценка sinx с использованием бесконечных рядов

Что я уже пробовал:

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

int main()
{
    int terms;
    int count=0;
    int sum = 0;int x;int n;
    printf("enter number of terms");
    scanf("%d",&terms);
    printf("enter value of x");
    scanf("%d",&x);
    while(count <= terms){

        n = 2*count+1;

        sum = sum + ((pow(-1,count))*(pow(x,n)/(fact(n))));
        count++;
    }
    printf("%d",sum);
    }
    int fact(int f){
    int number = 1;
    int product = 1;
    while(number<=f){

         product = number*product;
         number++;

    }
    return product;
}

Mehdi Gholam

.. а какой у вас вопрос (кроме изложения вашего домашнего задания)?

[no name]

Не используйте ints. Это реальные числа. http://www.cs.yale.edu/homes/aspnes/pinewiki/C(2Ф)FloatingPoint.html

Kornfeld Eliyahu Peter

Сделайте это ответом - в конце концов, это так...

[no name]

Вы должны изменить этот пост, чтобы сделать ваш вопрос ясным, потому что до сих пор нет никаких вопросов. Мы можем догадываться о вашей проблеме, но в этом нет никакого смысла.

2 Ответов

Рейтинг:
1

CPallini

Как было предложено, используйте doubles вместо int. Наслаждаться:

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

double fact(unsigned n)
{
  double result =1.0;
  unsigned int i;
  for (i=2; i<=n; ++i )
    result *= i;
  return result;
}

int main()
{
  unsigned terms;
  unsigned count=0;
  double result = 0.0;
  double angle;

  printf("enter number of terms ");
  scanf("%d",&terms);
  printf("enter value of x ");
  scanf("%lf",&angle);
  while(count <= terms)
  {
      double sign = count & 1 ? -1.0 : 1.0;
      unsigned n = 2*count+1;

      result += sign*(pow(angle,(double)n)/fact(n));
      count++;
  }
  double br = sin(angle);
  printf("approximation %g, builtin function result %g, difference  %5.2f%%", result, br, fabs(result-br)/br*100.0);
}


Daniel Pfeffer

Это будет крайне неточно даже для малых значений X. Вы должны, по крайней мере, использовать правило Хорнера для оценки многочлена. Смотрите мое решение для других соображений.

CPallini

Вы действительно пробовали это сделать?

Daniel Pfeffer

1. pow(x, y) _may_ имеет оптимизацию для случая интеграла y, но это не гарантируется. В противном случае он вычисляет exp(y*log(x)).
2. Даже если оптимизация существует, вы будете иметь между lg(n) и 2*lg(n) умножениями для расчета мощности _each_ со всеми связанными ошибками и дополнительными вычислениями.
3. Правило Хорнера - f(x) = (...((a[n]*x + a[n-1])*x + a[n-2])*x ...) +a[0] использует n умножений и n сложений для выполнения вычисления, которое является одновременно более быстрым и точным.
4. Современный компилятор C или C++ предоставляет фма(). Использование этого метода сводит вычисление к n операциям fma() с соответствующим повышением точности.
5. Также нет необходимости пересчитывать факториал на каждом этапе. Он может быть рассчитан "бесплатно", установив a[2*k+1] = +/-1.0/(2*k*(2*k+1)), a[1] = 1,0.
6. предполагая, что x даже умеренно велик (скажем, 100.0), ваш метод переполнится задолго до того, как вы достигнете приемлемой точности - вам понадобится по крайней мере 150 элементов (n = 300) и 300! переполнится задолго до того, как вы достигнете этого.

CPallini

Что такое "Х", которое вы написали в точке (6)?
Кстати, вы мне не ответили.

Daniel Pfeffer

x-это аргумент для вашего вычисления sin ().

Нет, я не запускал код; достаточно просто посмотреть, как вы реализовали степенной ряд. Были ли какие-либо мои комментарии по поводу кода неверными? :)

CPallini

Ваш подход кажется мне неправильным. ОП пытался реализовать серию Тейлора, и я помогал в этой самой теме.
Я думаю, что ваши замечания могут быть полезны для числовых экспертов. Если мне когда-нибудь понадобится грех(x) Я использую, ну встроенный грех(x). И нет, я обычно не предоставляю 100 в качестве аргумента для sin(x). Вы действительно хотите сказать, что 100-это небольшое значение x? Ерунда.

Daniel Pfeffer

При моделировании многих физических систем вы вычисляете sin(omega*t), где omega-частота, а t-время. Эти цифры могут быть довольно большими - намного больше 100,0.

Что касается вашего второго пункта, то мы должны согласиться не согласиться. :)

CPallini

Согласен. :-D

Рейтинг:
0

Daniel Pfeffer

Использование бесконечного ряда для вычисления функции займет много времени. Прежде чем сделать это, спросите себя:

1. Является ли функция периодической? Если да, то сведите аргумент к одному периоду.
2. Это чет или нечет (Ф(Х) == -ф(-х) или F(Х) == ф(-х) )? Если это так, запишите нечетную функцию, например x*F(x^2), и четную функцию, например G(x^2).
3. Существуют ли какие-либо другие атрибуты функции, которые могут помочь?

Как только вы это сделаете, вы обнаружите, что для получения требуемой точности требуется только конечное число элементов.

Удачи вам!