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

double factorial(int N){
  int i;
  double fct;
  fct=(double)1;
  for (i=2;i<=N;i++){
    fct*=i;
  }
  return fct;
}

double stirling(int N){
  double PI=3.14159265358979323846;
  double E =2.71828182845904523536;
  double strng;
  strng=sqrt(PI*2/N)*pow(((double)N)/E,N);
  return strng;
}
double stirling2(int N){
  double PI=3.14159265358979323846;
  double E =2.71828182845904523536;
  double strng;
  strng=sqrt(PI*2/N)*pow(((double)N)/E,N)*exp((double)1/12/N);
  return strng;
}
double stirling3(int N){
  double PI=3.14159265358979323846;
  double E =2.71828182845904523536;
  double strng;
  strng=sqrt(PI*2/N)*pow(((double)N)/E,N) \
    *exp((double)1/12/N-(double)1/360/N/N/N);
  return strng;
}
double stirlinglog(int N,int *iex){
  double PI=3.14159265358979323846;
  double E =2.71828182845904523536;
  double DL10E=0.43429448190325182765;
  double strng,dl;
  dl=log(PI*2/N)/2+log(((double)N)/E)*N \
    +((double)1)/12/N-((double)1)/360/N/N/N;
  dl=dl*DL10E;
  *iex=(int)dl;
  strng=pow((double)10,dl-*iex);
  return strng;
}

int main(void){
  unsigned long N;
  int iex;
  double strng;
  printf("Calculation of factorial by two methods.");
  printf("Give N : ");
  scanf("%lu",&N);
  printf("Value of direct multiplication : %18.16le\n",factorial(N));
  printf("Value of the Stirling formula  : %18.16le\n",stirling(N+1));
  printf("Value of the 2nd asymptotic    : %18.16le\n",stirling2(N+1));
  printf("Value of the 3rd asymptotic    : %18.16le\n",stirling3(N+1));
  strng=stirlinglog(N+1,&iex);
  printf("Striling through log           : %18.16lfe%d\n",strng,iex);
  return 0;
}
