At this point, Math::BigInt is working, modulo a few issues with meta-operators that seem to revolve around Rakudo bugs. I have implementations of the basic operators and comparison operators, though they probably could use some more tests. I took sorear++’s suggestion to use postfix L as the shortcut for creating BigInts. That lets you say things like
> my @fib := 1L, 1L, * + * ... *; > say @fib[200]; 453973694165307953197296969697410619233826
Much nicer than the code in my last blog post.
The catch here is that these new operators don’t work properly with Rakudo’s meta-ops:
> say [*] 1L .. 40L; 8.15915283247898e+47
The result should be a much longer integer rather than a Num, like this:
> say reducewith(&infix:<*>, 1L .. 40L); # this is what [*] should be doing internally 815915283247897734345611269596115894272000000000
But [*]
doesn’t see our new operators, so it calls the Real version of the operator, which in turn calls Math::BigInt.Bridge. That creates a Num version of the BigInt that Rakudo knows how to multiply, though of course, a lot of precision is lost in the process.
As a different approach to trying to meta-ops to work, I’ve also added L+
and L*
operators. The idea was that these do BigInt calculations even if both of their arguments are regular Ints:
> say reducewith(&infix:<L*>, 1 .. 40); 815915283247897734345611269596115894272000000000
Unfortunately, [L*]
still doesn’t work:
> [L*] 1..40; Could not find sub &infix:<L*>
Sigh.
Next up: Cleaning this up and adding it to the ecosystem. Math::FatRat. And talking with pmichaud about how to add arbitrary precision Ints directly into Rakudo.
Leave a comment