Функция для вычисления Пи с использованием ряда Тейлора в С++

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

вот мой код

#include <iostream>
#include <math.h>
#include <stdlib.h>
using namespace std;

double get_pi(double accuracy)
{
double estimate_of_pi, latest_term, estimated_error;
int sign = -1;
int n;

estimate_of_pi = 0;
n = 0;

do
{
    sign = -sign;
    estimated_error = 4 * abs(1.0 / (2*n + 1.0));  //equation for error
    latest_term = 4 * (1.0 *(2.0 * n + 1.0));      //calculation for latest term in series
    estimate_of_pi = estimate_of_pi + latest_term; //adding latest term to estimate of pi
    n = n + 1;                                     //changing value of n for next run of the loop
}
while(abs(latest_term)< estimated_error);

return get_pi(accuracy);

}

int main()
 {
    cout << get_pi(100);
 }

логика кода следующая:

  1. определить все переменные
  2. установить оценку числа пи равной 0
  3. вычислить член из ряда Тейлора и вычислить ошибку в этом члене
  4. затем он добавляет последний член к оценке pi
  5. затем программа должна вычислить следующий член ряда и ошибку в нем и добавить его к оценке числа пи до тех пор, пока не будет выполнено условие в операторе while.

Спасибо за любую помощь, которую я могу получить


person Aman Sood    schedule 11.05.2017    source источник


Ответы (3)


В вашей функции есть несколько ошибок. Смотрите мои комментарии со строками, начинающимися с "//ПРИМЕЧАНИЕ:".

double get_pi(double accuracy)
{
   double estimate_of_pi, latest_term, estimated_error;
   int sign = -1;
   int n;

   estimate_of_pi = 0;
   n = 0;

   do
   {
      sign = -sign;

      //NOTE: This is an unnecessary line.
      estimated_error = 4 * abs(1.0 / (2*n + 1.0));  //equation for error

      //NOTE: You have encoded the formula incorrectly.
      // The RHS needs to be  "sign*4 * (1.0 /(2.0 * n + 1.0))"
      //                       ^^^^          ^
      latest_term = 4 * (1.0 *(2.0 * n + 1.0));      //calculation for latest term in series
      estimate_of_pi = estimate_of_pi + latest_term; //adding latest term to estimate of pi
      n = n + 1;                                     //changing value of n for next run of the loop
   }

   //NOTE: The comparison is wrong.
   // The conditional needs to be "fabs(latest_term) > estimated_error"
   //                              ^^^^             ^^^
   while(abs(latest_term)< estimated_error);

   //NOTE: You are calling the function again.
   // This leads to infinite recursion.
   // It needs to be  "return estimate_of_pi;"
   return get_pi(accuracy);    
}

Кроме того, вызов функции в main неверен. Это должно быть:

get_pi(0.001) 

чтобы указать, что если абсолютное значение термина меньше 0,001, функция может вернуться.

Вот обновленная версия функции, которая работает для меня.

double get_pi(double accuracy)
{
   double estimate_of_pi, latest_term;
   int sign = -1;
   int n;

   estimate_of_pi = 0;
   n = 0;

   do
   {
      sign = -sign;
      latest_term = sign * 4 * (1.0 /(2.0 * n + 1.0));  //calculation for latest term in series
      estimate_of_pi += latest_term;                    //adding latest term to estimate of pi
      ++n;                                              //changing value of n for next run of the loop
   }
   while(fabs(latest_term) > accuracy);

   return estimate_of_pi;
}
person R Sahu    schedule 11.05.2017
comment
спасибо, приятель, я заметил несколько вещей, которые вы упомянули после того, как написал, теперь изменил свой, и он работает как задумано, еще раз спасибо - person Aman Sood; 11.05.2017

Ваше заявление о возврате может быть причиной.

Попробуйте вернуть "estimate_of_pi" вместо get_pi(точность).

person elMentat    schedule 11.05.2017

Ваше условие разрыва можно переписать как

2*n + 1 < 1/(2*n + 1)     =>   (2*n + 1)^2 < 1

и это никогда не будет true для любого положительного n. Таким образом, ваш цикл никогда не закончится. После исправления этого вы должны изменить оператор return на

return estimated_error;

В настоящее время вы вызываете функцию рекурсивно без конца (при условии, что вы исправили условие остановки).

Более того, у вас есть sign и параметр accuracy, которые вы вообще не используете в расчетах.

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

person 463035818_is_not_a_number    schedule 11.05.2017