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

void integer_method(void);
void integer_check(void);


double a,aelk,u;

double lower, upper, ustore, ucheck;

long i,k,m,n;

int iflag = 0;
int ic;

void main()
{
	printf("\n\n\n  factorial,  ver 1.1,  \n\n  By Tom Irvine   Email: tomirvine@aol.com \n");
	printf("\n This program calculates the factorial of a number. ");
	printf("\n The number may be any rational number, greater than or equal to zero.  ");
	printf("\n Example:  the number could be 2.4571  \n\n");


	while(1)
	{
        ic=0;

	
		printf("\n\n Enter number \n");

		scanf("%lf", &u);

		if(u > 170 )
		{
			printf("\n\n Number must be  <= 170 \n\n Press any key to exit.\n");
			getch();
		
			exit(1);
		}
		if( u < 0. )
		{
			printf("\n\n Number must be >= 0 \n\n Press any key to exit.\n");
			getch();
		
			exit(1);
		}
	
	

		{
			ic=1;

			ucheck = u;


			integer_check();

			if(ic==1)
			{
				long nk=1;

				printf("\n\n calculating.");
			
				ustore = u+1;
				
				u=long(u);
				integer_method();
				
				lower = a;
                upper = lower*(u+1);


	           

				double abefore = 1.;

				for(m=1; m<=8000000; m++)
				{
					if(nk==30000)
					{
						printf(".");
						nk=0;
					}
					nk++;
				
					double nx = pow(m,ustore);

					a=1.;

					if(m==1)
					{
						for(k=1; k<=m; k++)
						{
							a*=double(k);
							a/=(ustore + double(k));
						}
						a/=ustore;
					}
					else
					{
						a=abefore*double(m)/(ustore+double(m) );
					}

		

					if( m > 5 )
					{

						if(fabs(a*pow(m,ustore) - abefore*pow((m-1),ustore) )/a*pow(m,ustore) < 1.0e-09)
						{ break; }

					}

					abefore = a;

//					printf("\n m=%ld a=%lf",m,a );

					aelk=a*pow(m,ustore);

				}
				
				
			}

			if( iflag == 0 )
			{
				printf("\n\n %12.7g! = %14.8g ",ucheck,aelk);
			} 

		}
	
		printf("\n\n");
		printf("\n press 1 for another calculation ");
		printf("\n       2 to exit \n");

		scanf("%ld", &i);

		if( i == 2 ){ break;}
	}

 
	
}
void integer_method(void)
{

		a=1.;

		n=long(u);

		for(i=1; i<=n; i++)
		{
			a*=i;
		}
}
void integer_check(void)
{


	int jk;

    for(jk=0; jk<=200; jk++)
    {


		if( fabs(ucheck-double(jk)) < 1.0e-06)
		{
			u=long(jk);

			integer_method();


			aelk=a;

			ic=0;

			break;
		}
	}

}
