2016-11-08 20 views
-1

Привет, поэтому я рассмотрел другие вопросы на этом сайте относительно приближения Стирлинга, но ни один из них не был полезным. Я предполагаю вычислить факториал, а также аппроксимировать факториал из двух уравнений приближения Стирлинга. Затем я помещаю их в таблицу всех значений, ведущих к вводу пользователя, если вход меньше или равен 14. Или я помещаю их в другую таблицу всех значений приближений, ведущих к вводу пользователя в кратные 5. Я много пробовал, но не знаю, где я ошибся.Вычисление аппроксимации Стирлинга в C

Мне просто интересно, как получить правильные значения для приближений? Я уже получил факториал.

Вот весь код:

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

#define PI 3.141592653589793 
#define e 2.71828 
#define TRUE 1 
#define FALSE 0 

long long fact(int i); 
double stirling1(int i); 
double stirling2(int i); 

/*--------------------------- main function ------------------------------- 
Purpose: The purpose of this program is to give the user the value of the 
factorial of the nonnegative integer the user inputs. 
---------------------------------------------------------------------------*/ 

int main() 
{ 
char ch = 'y'; 
int flag, again; 
int n; 
int i; 

again = TRUE; 

while (again == TRUE) 
{ 
    printf("Please enter a nonnegative integer:\n"); //ask the user for the input 
    flag = scanf("%d", &n); 

    if (flag != 1) 
    { 
     while ((getchar()) != '\n'); 
    } 

    if (flag != 1) //run this statement if the user inputs a noninteger 
    { 
     printf("Input must be an integer.\n"); 
     continue; 
    } 

    else if (n < 0) //run this statement if the user inputs a negative integer 
    { 
     printf("The factorial is undefined for negative arguments.\n"); 
     continue; 
    } 

    else if (n <= 14) //run this statement if the user inputs an integer less than or equal to 14 
    { 
     printf("Number  Factorial Approximation   Approximation2\n------------------------------------------------------------------\n"); //prints the header for first table 

     for (i = 1; i <= n; ++i) 
      { 
       printf("%d  %14lld  %e   %e\n", i, fact(i), stirling1(i), stirling2(i)); //calls functions to input factorials 
      } 
    } 

    else //run this statement if the user inputs a number greater than 14 
    { 
     printf("Number Approximation1   Approximation2\n-----------------------------------------------------\n"); //prints the header for second table 

     for (i = 1; i != n; ++i) 
     { 
      i *= 5; 
      printf("%d  %e   %e\n", i, stirling1(i), stirling2(i)); //calls functions to input approximate factorials 
     } 
    } 

    printf("Do you want to compute another factorial? (y/n):"); //ask user if they want another factorial of a different number 
    scanf(" %c", &ch); 

    if (ch != 'y') 
     again = FALSE; //if user does not input 'y' then do not compute another factorial 
} 

printf("**** Program Terminated ****\n"); //ends program 

} 

long long fact(int i) //function to find exact factorial 
{ 
if (i <= 1) 
{ 
    return 1; 
} 

else 
{ 
    return i * fact(i-1); 
} //return exact factorial to main 
} 

double stirling1(int i) //function to find first approximate factorial 
{ 
int stirling_ans1; 

stirling_ans1 = pow(i , i) * sqrt(2.0 * PI * i) * exp(-i); //equation to find first approximate factorial 

return stirling_ans1; //return approximate factorial to main 
} 

double stirling2(int i) //function to find second approximate factorial 
{ 
int stirling_ans2; 

stirling_ans2 = pow(i, i) * pow(e, -i) * sqrt(2 * PI * i) * (1 + (1/(12 * i))); 
//equation to find second approximate factorial 

return stirling_ans2; //return approximate factorial to main 
} 

Вот код для двух аппроксимирующих функций а именно:

double stirling1(int i) //function to find first approximate factorial 
{ 
int stirling_ans1; 

stirling_ans1 = pow(i , i) * sqrt(2.0 * PI * i) * exp(-i); //equation to find first approximate factorial 

return stirling_ans1; //return approximate factorial to main 
} 

double stirling2(int i) //function to find second approximate factorial 
{ 
int stirling_ans2; 

stirling_ans2 = pow(i, i) * pow(e, -i) * sqrt(2 * PI * i) * (1 + (1/(12 * i))); 
//equation to find second approximate factorial 

return stirling_ans2; //return approximate factorial to main 
} 

И где функции приближения были реализованы в главной функции:

else if (n <= 14) //run this statement if the user inputs an integer less than or equal to 14 
    { 
     printf("Number  Factorial Approximation   Approximation2\n------------------------------------------------------------------\n"); //prints the header for first table 

     for (i = 1; i <= n; ++i) 
      { 
       printf("%d  %14lld  %e   %e\n", i, fact(i), stirling1(i), stirling2(i)); //calls functions to input factorials 
      } 
    } 

    else //run this statement if the user inputs a number greater than 14 
    { 
     printf("Number Approximation1   Approximation2\n-----------------------------------------------------\n"); //prints the header for second table 

     for (i = 1; i != n; ++i) 
     { 
      i *= 5; 
      printf("%d  %e   %e\n", i, stirling1(i), stirling2(i)); //calls functions to input approximate factorials 
     } 

Любая помощь для получения правильных приближений будет оценена по достоинству.

+0

'INT stirling_ans1;' -> 'двойной stirling_ans1;' (различные места). Зачем присваивать 'double' результат' int'? Если код необходимо округлить, используйте 'round()' или 'rint()' и т. Д. – chux

+0

'1/(12 * i)' is 'int' math. Предложите '1.0/(12 * i)' – chux

+0

Спасибо вам большое! Это поставило проблему. –

ответ

2

Код OP выполняет слабую или неправильную математику не менее чем в 2 местах.

1/(12 * i)int математика, а не необходимая FP 1.0/(12 * i).

Код "rounds", пройдя через int. Но это, в лучшем случае, усекает в сторону 0.0. Лучше использовать double stirling_ans1; чем int stirling_ans1;


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

#define PI 3.1415926535897932384626433832795 
#define e 2.7182818284590452353602874713527 

Или еще лучше, форма значения из расчета единовременного:

double pi = acos(-1.0); 
double e = exp(1.0);