Question

I came across a problem of calculating 100 factorial.

Here is what I tried first in Perl to calculate 100! :

#!/usr/bin/perl

use strict;
use warnings;
use Math::BigInt;

my $n=<>;
chomp($n);
print fac($n);

sub fac
{
    my ($m) = @_;

    return 1 if($m <=1 );
    return $m*fac($m-1);
}

But this is giving me 9.33262154439441e+157.

I need the answer with all of the digits.

What do I do?

Was it helpful?

Solution

Doubles (which most Perls use) only have ~16 digits of precision. You need to use another system to get the 158 digits of precision you need.

use bigint;

This will cause Perl to automatically treat all numbers in your script as Math::BigInt objects.

If you need finer control (to treat some numbers as BigInt and some numbers as floating point) then see Krishnachandra Sharma's solution and explicitly use the Math::BigInt constructor.

Math::BigInt has a builtin factorial function, by the way:

$ perl -MMath::BigInt -e 'print Math::BigInt->bfac(100)'
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

OTHER TIPS

Doubles (which most Perls use) only have ~16 digits of precision. You need to another system to get the 158 digits of precision you need. Try using Math::BigInt.

Here is the code.

#!/usr/bin/perl

use strict;
use warnings;
use Math::BigInt;


my $n=100;
Math::BigInt->new($n);
print fac($n);

sub fac
{
    my ($m) = @_;

    return 1 if($m <=1 );
    return Math::BigInt->new($m*fac($m-1));
}

Produces 9332621544394415268169923e266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

By definition, bigint works by overloading handling of integer and floating point literals, converting them to Math::BigInt objects. So with the help of simple for loop we can achieve the factorial of very big integers.

use bigint;

my $fact = 1;

for my $n (1..100) {    
    $fact *= $n;
}

print "Factorial: \n", $fact , "\n";

This produces the below output:

Factorial: 933262154439441526816992388562667004907159682643816214685929638952175
99993229915608941463976156518286253697920827223758251185210916864000000000000000
000000000

whereas the normal program like this would tremble with no meaningful output

use integer;

my $fact = 1;

for my $n (1..100) {    
    $fact *= $n;
}

print "Factorial: \n", $fact , "\n";

Output:

Factorial:
0
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top