monkfan has asked for the wisdom of the Perl Monks concerning the following question:
Stirling method indeed gives a faster result:#!/usr/bin/perl -w use strict; my $h =8; my $pure = factorial_pure($h); my $stirling = factorial_stirling($h); print "PURE : $pure\n"; print "STIRLING : $stirling\n" #------Subroutines------------ sub factorial_stirling{ my $n = shift; use constant PI => 4*atan2 (1,1); use constant e => exp(1); my $log_nfact = $n * log ($n) - e* log($n) + 0.5 * (log(2*PI)+log($n)); # Below is Tilly's suggestion, with less accuracy # $n * log ($n) - ($n) + (0.5 * (log(2+ log(PI))+log($n))); return exp($log_nfact); } sub factorial_pure { my ($n,$res) = (shift,1); return undef unless $n>=0 and $n == int($n); $res *= $n-- while $n>1; return $res; }
With a reasonable approximation:Rate pure stirling pure 290034/s -- -30% stirling 319835/s 16% --
But when it comes to large N, e.g $h = 500. It began to fail.PURE : 40320 STIRLING : 417351.253768542
|
---|