Abstract: This article only discusses the Approximate Calculation of 16-bit valid numbers. Unlike the previous article, it uses a mathematical formula called Sterling to calculate. It can calculate the factorial of a large number, but its accuracy is low.
In "step-by-step computing from entry to proficient-one of approximate computing", we use two numbers to represent intermediate results, so that the computing range is extended to 10 million, and can complete 0.02 in 10000000 seconds! . Is there a faster algorithm while keeping the number close to 16 valid digits. Fortunately, there is a formula named Stirling that can quickly calculate a factorial of a large number. The larger the number, the higher the accuracy. There is a http://mathworld.wolfram.com to find Stirling's
Series can find two formulas that use the 'string' formula to calculate the factorial. One is the common form and the other is the logarithm form. The previous formula contains an Infinite Series sum. The formula for the first five items of a series is n! = SQRT (2 * pI * n) * (N/E) N * (1 + 1/12/n + 1/288/N2-139/51840/n3-571/2488320/N4 + ...), Here pi is the circumference rate, and E is the base of the natural logarithm. The last formula is also in the form of an Infinite Series sum. It is generally referred to as the Stirling series, including the N of the first three items of the series! The logarithm formula is ln (N !) = 0.5 * ln (2 * PI) + (n + 0.5) * ln (N)-N + (1/12/n
-1/360/N3 + 1/1260/N5 )-..., The following two formulas are used to calculate n respectively !. The complete code is as follows:
# Include "stdafx. H "# include" math. H "# define pi3.1415926535897932384626433832795 # define returns bignum {double N; // The inte of the ending part indicated by scientific notation; // The exponent portion indicated by scientific notation. If a bignum is X, this X = N * 10 ^ e}; const double A1 [] = {1.00, 1.0/12.0, 1.0/288,-139/51840,-571.0/2488320.0 }; const double A2 [] = {1.0/12.0,-1.0/360, 1.0/1260.0}; void printfresult (struct bignum * P, char buff []) {While (p-> N> = 10.00) {P-> N/= 10.00; P-> E ++;} sprintf (buff, "%. 14fe % d ", p-> N, P-> E);} // n! = SQRT (2 * pI * n) * (N/E) ^ N * (1 + 1/12/n + 1/288/n ^ 2-139/51840/n ^ 3-571/2488320/n ^ 4 + ...) Void calcfac1 (struct bignum * P, int N) {double logX, S, // series and item; // each int I of the series; // x ^ n = POW (10, N * log10 (x); logX = N * log10 (double) N/E); P-> E = (INT) (logX); P-> N = POW (10.0, logX-p-> E); P-> N * = SQRT (2 * pI * (double) N ); // evaluate (1 + 1/12/n + 1/288/n ^ 2-139/51840/n ^ 3-571/2488320/n ^ 4 + ...) For (item = 1.0, S = 0.0, I = 0; I <sizeof (A1)/sizeof (double); I ++) {S + = item * A1 [I]; item/= (double) N; // item = 1/(n ^ I)} p-> N * = s ;} // Ln (N !) = 0.5 * ln (2 * PI) + (n + 0.5) * ln (N) -N + (1/12/n-1/360/n ^ 3 + 1/1260/n ^ 5 -...) void calcfac2 (struct bignum * P, int N) {double logr; double S, // series and item; // each int I of the series; logr = 0.5 * log (2.0 * PI) + (double) N + 0.5) * log (N)-(double) N; // s = (1/12/n-1/360/n ^ 3 + 1/1260/n ^ 5) for (item = 1/(double) N, S = 0.0, I = 0; I <sizeof (A2)/sizeof (double); I ++) {S + = item * A2 [I]; item/= (double) (n) * (double) n; // item = 1/(n ^ (2I + 1)} logr + = s; // according to the bottom-up formula, log 10 (n) = ln (N)/ln (10) p-> E = (INT) (logr/log (10); P-> N = POW (10.00, logr/log (10)-P-> E);} int main (INT argc, char * argv []) {struct bignum R; char buff [32]; int N; printf ("n =? "); Scanf (" % d ", & N); calcfac1 (& R, n); // calculate the factorial printfresult (& R, buff); // convert the result into a string printf ("% d! = % S by method 1/N ", N, buff); calcfac2 (& R, n); // use the second method to calculate the factorial printfresult (& R, buff); // convert the result into a string printf ("% d! = % S by method 2/N ", N, buff); Return 0 ;}
Liangbch@263.net, copyright, reprinted please indicate the source.