http://www.perlmonks.org?node_id=1229931


in reply to Math With Big Numbers

Maybe this can shed some light. In this first example we see that the number is stored as an NV (numeric value) which is different from an IV (integer value) or UV (unsigned integer value). The reason is that 6**25 would overflow an IV or UV, so the only reasonable ways to store it would be as an NV (a double precision float) or a string. But there hasn't been any stringification, so you get the NV:

perl -MDevel::Peek -e 'my $n = 6**25; Dump($n)' SV = NV(0x563681e7c888) at 0x563681e7c8a0 REFCNT = 1 FLAGS = (NOK,pNOK) NV = 2.84302880299297e+19

You want full precision. So you try this:

perl -MO=Deparse -MMath::BigInt -e 'my $bi = Math::BigInt->new(6**25); +' my $bi = 'Math::BigInt'->new(2.84302880299297e+19);

Well, that didn't work. Why? Because 6**25 gets computed before Math::BigInt gets a chance to see it, so by the time Math::BigInt gets it, you've already lost precision.

What else should we try? How about decomposing it to the constituent parts of the equation, passing those normal-sized ints to Math::BigInt, and then asking that module to do the magic for you?

perl -MMath::BigInt -e 'my $bi = Math::BigInt->new(6)->bpow(25); print + $bi, "\n";' 28430288029929701376

That looks better.


Dave