#!/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)