One of the neat things of Raku is that it automatically uses rational numbers instead of floating point numbers, when appropriate (e.g. when dividing two integers). Unfortunately, once the denominator gets too large, floating point numbers are used anyway.
There is the FatRat
type that doesn't do that, but as far as I can find, the only way to use those is to explicitly do so.
For instance, this script calculates digits of π:
#!/usr/bin/env raku
unit sub MAIN(Int $decimals = 1_000);
sub atan_repr(Int $n, Int :$decimals)
{
my $x = $n;
my $n2 = $n²;
my $sign = 1;
my $limit = 10**($decimals+2);
my $result = FatRat.new(1, $x);
for 3,5...* -> $i {
$x ×= $n2;
$sign ×= -1;
$result += FatRat.new($sign, $i × $x);
last if $x ≥ $limit;
}
return $result;
}
my $π = 4 × (4 × atan_repr(5, :$decimals) - atan_repr(239, :$decimals));
my $π-str = ~$π; # Make sure we don't do string conversion over and over
print '3. ';
for 0,5...^$decimals -> $d {
print " # $d\n " if $d && $d %% 50;
print $π-str.substr(2+$d,5), ' ';
}
print " # $decimals" if $decimals && $decimals %% 50;
say '';
It's pretty elegant, except for stuff like FatRat.new(1, $x)
. I'd much rather be able to use just 1/$x
and declare somehow that FatRat
s should automatically be used instead of Rat
s. Perhaps something like use bigrat
, similar to Perl's use bigint
and use bignum
?
Is there a way to do this that I haven't found?