Форум программистов, компьютерный форум CyberForum.ru

При больших значениях х ряд считает направильно - C++

Восстановить пароль Регистрация
 
 
vladislav23
0 / 0 / 0
Регистрация: 28.04.2013
Сообщений: 24
19.09.2013, 11:08     При больших значениях х ряд считает направильно #1
При больших значениях х ряд считает направильно с чем это может быть связано, вот код и сам ряд:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
   double result=1;
   long int j=2;
   bool minus=true;
   double cur=x;
   double prev=0;
   double f=0;
   do
   {
      cur=pow(x,j);
      
      if (minus)
      {
         cur=cur*(-1.0);
      }
      f=1.0;
      for (long int i=1;i<=j;i++)
      {
         f=f*i;
      }
      cur=cur/f;
      result=result+cur;
      double testval=fabs(prev)-fabs(cur);
      if (j>2&&testval<=e)
      {
         break;
      }
      
      minus=!minus;
      prev=cur;
      j+=2;
   } while (1);
   return result; 
}
Изображения
 
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nekto
342 / 287 / 10
Регистрация: 23.03.2012
Сообщений: 838
19.09.2013, 11:12     При больших значениях х ряд считает направильно #2
C++
1
2
3
4
if (minus)
      {
         cur=cur*(-1.0);
      }
Тут не нужна проверка. Знак меняться должен на каждой итерации.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
19.09.2013, 11:41     При больших значениях х ряд считает направильно #3
Код конечно капец.
Если вот это проверка точности
C++
1
double testval=fabs(prev)-fabs(cur);
То должен вас расстроить ошибку ряда нужно вычислять по остаточным членам, например в форме Лагранжа.
Возможно такой алгоритм подойдет больше?
C++
1
2
3
4
5
6
7
    double xSled = 1.0,//член ряда
 sum = 0.0;//сумма ряда
    do
    {
        sum += xSled;
    }
    while((xSled *= - x * x /(2 * j *(2 * j - 1))) > precision);//проверяем точность
vladislav23
0 / 0 / 0
Регистрация: 28.04.2013
Сообщений: 24
19.09.2013, 11:56  [ТС]     При больших значениях х ряд считает направильно #4
В задании указано проверять точность по этой формуле
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
19.09.2013, 12:02     При больших значениях х ряд считает направильно #5
Цитата Сообщение от vladislav23 Посмотреть сообщение
В задании указано проверять точность по этой формуле
По той которая написанна у вас?
vladislav23
0 / 0 / 0
Регистрация: 28.04.2013
Сообщений: 24
19.09.2013, 12:09  [ТС]     При больших значениях х ряд считает направильно #6
Да.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
19.09.2013, 12:15     При больших значениях х ряд считает направильно #7
Ну тогда получаете то что имеете. Ознакомтесь с этим.
Любой ряд со стремящимися к нулю членами по вашей формуле рано или позно даст сумму с какой-то точность. А теперь рассмотрим например гармонический ряд. Его члены стремяться к нулю, однако сам ряд расходится. Так что выбросьте задачник в топку и подтяните математику.
Nekto
342 / 287 / 10
Регистрация: 23.03.2012
Сообщений: 838
19.09.2013, 12:16     При больших значениях х ряд считает направильно #8
double f=0; - меняй на unsigned long long f;
Catstail
Модератор
 Аватар для Catstail
21501 / 10254 / 1670
Регистрация: 12.02.2012
Сообщений: 17,139
19.09.2013, 12:25     При больших значениях х ряд считает направильно #9
Цитата Сообщение от Nekto Посмотреть сообщение
double f=0; - меняй на unsigned long long f;
- ни в коем случае! Только double!

Цитата Сообщение от Ilot Посмотреть сообщение
Так что выбросьте задачник в топку и подтяните математику.
- нет, задачник не виноват. И гармонический ряд здесь не при чем. Виновата машинная математика.

Ряд для косинуса сходится абсолютно при любом вещественном х. Но дело в том, что вещественное число - это зачастую бесконечная дробь, а машинная арифметика работает с длинными, но конечными дробями. Это вызывает т.н. погрешность ограничения. И эта погрешность копится (особенно для рядов типа sin/cos) и, в конце концов, способна исказить результат до полного абсурда. Мало кто из программистов (особенно начинающих) это понимает...

Рекомендую старую, но очень хорошую книгу Мак-Кракен, Дорн "Численные методы и программирование на Фортране". Там этот вопрос хорошо рассмотрен в одной из первых глав.
Nekto
342 / 287 / 10
Регистрация: 23.03.2012
Сообщений: 838
19.09.2013, 12:28     При больших значениях х ряд считает направильно #10
Цитата Сообщение от Catstail Посмотреть сообщение
- ни в коем случае! Только double!
И терять точность, начиная с определенного этапа.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
19.09.2013, 12:29     При больших значениях х ряд считает направильно #11
Catstail, благодрю за информацию, но вы не поняли о чем идет речь.
Разность членов гармонического ряда стремиться к нулю, однако сам ряд не сходится, поэтому формула которой пользуется vladislav23 не даст правильно результата. Т.е. он пользуется неправильной формулой для оценки остатка.
Catstail
Модератор
 Аватар для Catstail
21501 / 10254 / 1670
Регистрация: 12.02.2012
Сообщений: 17,139
19.09.2013, 12:30     При больших значениях х ряд считает направильно #12
PS здесь книга
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
19.09.2013, 12:42     При больших значениях х ряд считает направильно #13
Catstail, от души благодаю. Это именно то что мне нужно так как сам собираюсь заниматься именно численными методами. Может еще что-нибудь посоветуете(особенно интересуют ур. в часных производных)?
Nekto
342 / 287 / 10
Регистрация: 23.03.2012
Сообщений: 838
19.09.2013, 12:47     При больших значениях х ряд считает направильно #14
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <iomanip>
 
int main()
  {
  std::cout << "Enter x: ";
  long double x;
  std::cin >> x;
  std::cout << "Enter eps: ";
  long double eps;
  std::cin >> eps;
  long double sum = 1;
  long double numerator = 1;
  unsigned long long denominator = 1;
  unsigned long step_factorial = 2;
  long double current = 100500;
  long double sign = 1;
  long double last;
  do
    {
    sign *= -1;
    numerator *= x*x;
    denominator *= step_factorial * (step_factorial - 1);
    step_factorial += 2;
    last = current;
    current = numerator / denominator;
    sum += sign * current;
    }
  while (fabs(last - current) > eps);
  std::cout << "Result = " << std::setprecision(LDBL_DIG) << sum << std::endl;
  std::cin.ignore();
  std::cin.get();
  return 0;
  }
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
19.09.2013, 13:13     При больших значениях х ряд считает направильно #15
Nekto, Catstail все таки прав нужно знать как оценивать ошибки, а не использовать оч. большие числа в надежде, что ошибка скроется где-то в глубине после запятой.
При больших x всего-то навсего следует пользоваться формулами приведения к стандартному отрезку [-pi, pi]. Мотайте на ус. И не нужно вам ни каких long long.
Nekto
342 / 287 / 10
Регистрация: 23.03.2012
Сообщений: 838
19.09.2013, 13:15     При больших значениях х ряд считает направильно #16
Цитата Сообщение от Ilot Посмотреть сообщение
Nekto, Catstail все таки прав нужно знать как оценивать ошибки, а не использовать оч. большие числа в надежде, что ошибка скроется где-то в глубине после запятой.
При больших x всего-то навсего следует пользоваться формулами приведения к стандартному отрезку [-pi, pi]. Мотайте на ус. И не нужно вам ни каких long long.
Я не проводил анализ, как быстро оно будет сходиться.
Ilot
Модератор
Эксперт С++
1767 / 1142 / 223
Регистрация: 16.05.2013
Сообщений: 3,020
Записей в блоге: 5
Завершенные тесты: 1
19.09.2013, 13:23     При больших значениях х ряд считает направильно #17
Цитата Сообщение от Nekto Посмотреть сообщение
Я не проводил анализ, как быстро оно будет сходиться.
При такой оценке оно вообще может не сходится. Рекомендую прочитать посты выше.
Nekto
342 / 287 / 10
Регистрация: 23.03.2012
Сообщений: 838
19.09.2013, 13:42     При больших значениях х ряд считает направильно #18
Цитата Сообщение от Ilot Посмотреть сообщение
При такой оценке оно вообще может не сходится. Рекомендую прочитать посты выше.
Есть картинка с формулой, которую надо реализовать. Остальные ограничения, что это именно косинус, а не просто любая функция с именем cos, и поэтому можно уменьшать х без потери результата, это уже дополнительный анализ, чего в стартовом посте не было.
Catstail
Модератор
 Аватар для Catstail
21501 / 10254 / 1670
Регистрация: 12.02.2012
Сообщений: 17,139
19.09.2013, 14:06     При больших значениях х ряд считает направильно #19
Цитата Сообщение от Nekto Посмотреть сообщение
И терять точность, начиная с определенного этапа.
- и как ты на long long int вычислишь x/n! ?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.09.2013, 14:31     При больших значениях х ряд считает направильно
Еще ссылки по теме:

Вычислить интеграл при двух значениях шага интегрирования (h=0.1 и h=0.01). C++
C++ Вычислить значение функции Y (x) при различных значениях исходных данных x и а
Вывести на экран дисплея сообщения о значениях функции при различных значениях аргумента C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
monolit
179 / 179 / 21
Регистрация: 24.03.2011
Сообщений: 641
Завершенные тесты: 1
19.09.2013, 14:31     При больших значениях х ряд считает направильно #20
заменить это
Цитата Сообщение от vladislav23 Посмотреть сообщение
testval=fabs(prev)-fabs(cur)
На это
Цитата Сообщение от Nekto Посмотреть сообщение
while (fabs(last - current) > eps
очень здравая мысль, но хватит тут и double.
А вот
Цитата Сообщение от Nekto Посмотреть сообщение
numerator *= x*x;
* * denominator *= step_factorial * (step_factorial - 1);
* * step_factorial += 2;
явно лишнее. Достаточно хранить текущий член ряда, и следующий, и все. Из предыдущего получить следующий путем prev*x*x/((j-1)*j)

Там кода вообще на 10 строчек, а тут целое сочинение пишут...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
  {
  std::cout << "Enter x: ";
  double x;
  std::cin >> x;
  std::cout << "Enter eps: ";
  double eps;
  std::cin >> eps;
  sum = 1;
  double cur, prev = 1;
  for(int i = 2; ; i+=2) {
    prev = cur;
    cur *= -1*x*x/(i*(i-1));
    sum += cur;
    if (abs(abs(cur)-abs(prev))<eps) break;
  }
   cout << summ << endl;
  return 0;
  }
Вот.
Yandex
Объявления
19.09.2013, 14:31     При больших значениях х ряд считает направильно
Ответ Создать тему
Опции темы

Текущее время: 05:43. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru