or when absolute precission is not required, and in pure perl:
#!/usr/bin/perl
use Time::HiRes 'time';
my $next = 1;
my @log;
my @fact=(0);
sub more_logs {
my $n = shift;
for ($next..$n) {
my $log =log($_);
$log[$_] = $log;
$fact[$_] = $fact[$_-1]+$log;
}
$next = $n+1;
}
more_logs(10);
my $l10 = $log[10];
my $il10 = 1.0/$l10;
for (@ARGV) {
my $start = time;
more_logs($_) if $_ >= $next;
my $fact = $fact[$_];
my $exp = int $fact*$il10;
my $man = exp($fact-$exp*$l10);
my $end = time;
printf("%d! = %0.10fE%d (time: %f-%f)\n", $_, $man, $exp, $start,
+$end)
}
__END__
$ perl /tmp/bigfact.pl 1000 700 600 2000 5000
1000! = 4.0238726008E2567 (time: 1118757636.805467-1118757636.810242)
700! = 2.4220401248E1689 (time: 1118757636.810742-1118757636.810792)
600! = 1.2655723162E1408 (time: 1118757636.810928-1118757636.810945)
2000! = 3.3162750925E5735 (time: 1118757636.811015-1118757636.816799)
5000! = 4.2285779269E16325 (time: 1118757636.816961-1118757637.117728)