Let me start by saying that this will be the last article exploring peculiarities of Perl 6’s maths functions. I promise. At least for a while. With that said, let’s dive back into rational numbers vs floating point one last time.

Binary representation of the floating point number 0.15625. CC © Wikimedia Commons.

Back in number 4 of this series, I tried to figure out the precision of Perl 6‘s ’rational numbers compared to Cobol’s fixed precision types. That may sound like a strange thing to do, but I had just read an article about why Cobol still was preferred by financial institutions (read it if you haven’t already — this article will be easier to understand if you do, especially why the particular algorithm below is used to check precision). It had to do with how Cobol could control floating point precision to avoid rounding errors that accumulated over time could cost banks, stock exchanges, the IRS, etc., millions of dollars. The author proved that by comparing a little Python snippet to Cobol, a script that broke Python in all the expected ways.

Since Perl 6 use the Rat (rational) data type under the hood for lots of things, even without explicit typing on the programmer’s part, my hypothesis was that Perl 6 wouldn’t have these kinds of errors at all. So I made a Perl 6 implementation of the error provoking algorithm outlined in the Cobol article. And wouldn’t you know it: Perl 6 didn’t have the errors mentioned in the Cobol article. I proudly spread that conclusion in my Having fun with Rats post.

As it turns out I was a little too trigger happy. In my article I just tested the algorithm to 20 iterations since that was what the Cobol article did. When tinkering with the code afterwards I found that my Perl 6 code broke at around 28 iterations. So although it fared better than Python, and went beyond the Cobol example, even Perl 6 wasn’t foolproof.

That made me think: What if I implemented it using explicit typing, this time forcing the use of FatRats? So I did:

#!/usr/bin/env perl6 sub rec(FatRat $y, FatRat $z) {

return 108 — (815–1500/$z)/$y;

} sub default-behavior(Int:D $N) {

my @x = FatRat.new(4), FatRat.new(17, 4);

for (2..$N+1) -> $i {

my $n = rec(@x[$i-1], @x[$i-2]);

@x.append($n);

}

return @x;

} my @y = default-behavior(2000); for @y.kv -> $i, $p {

say $i.fmt(“%02d”) ~ “ | “ ~ @y[$i].fmt(“%3.20f”);

say join “ / “, @y[$i].nude;

}

As you can see I ran the code up to 2000 iterations. And Perl 6 didn’t break once. I figure I could continue much longer, but that wouldn’t prove my point any more than it already had: FatRats seemingly handle everything.

At around 2000 iterations, the floating point representation was an even 5. The FatRat had increased to something beyond readable:

2001 | 5.00000000000000000000

10887262270271520844470244368473590369823879678381735770804366536872861066757834267230923438499734851331955108971818900795255377964985420406353488530653796076376888302887871648059636404237386779810073204677465433988288796371463779266725835301768375910295365966893549342070113935097170738554786589822697649361389182715711445880206813457196212233603705832810491425136584469585820510373307587755977621707298634317089590138855983741462833338843271340817765566670690233393031687431055903364260747271559744687940769179892188275670612186517021074968728089773868903232112413409395441640658761326225416663244033887317133246740410946847989349983326675880888985445567168787598735624717364724914686476958266124806775762813974242476406932409145206237566267025023985919713838560053160634848162125063714368558880445253361406701423828947352575925454715484530130867655804116616415778049891344295072286232982121196487495343247308360407488300676499377578310332816377975448193225536813649463486171661227928324492008794414474774496406886870868799498753785243478428165856592662574587026062708505894963955557204003803392615937919983143327086591424359681275817919140507987737463394218763462404759849484338109892177212883565977961986616331952406228280515381736751779687947623033277314097434771424807829329022829618524311375471611964574251871376643107540529697952215346315210658268262117062285956468458853775876425932095612817 / 2177452454054304168894048873694718073964775935676347154160873307374572213351566853446184687699946970266391021794363780159051075592997084081270697706130759215275377660577574329611927280847477355962014640935493086797657759274292755853345167060353675182059073193378709868414022787019434147710957317964539529872277836543142289176041362691439242446720741166562098285027316893917164102074661517551195524341459726863417918027771196748292566667768654269212275864367729012474591108985007522990289641915425059624720960922390197391499416012195286133802412263320144198333588435944700149853436940773893604588831895901210854703334389818287374956988979446767663405991767869404053875825243861633344428650812796466524645611445569036116412001976972688038699652154919003410804565289198476051171009210210514432258823939333189758824739429056132928366378633982114880626729252784764043010629666202312909247751673764726461337254048195958324091876383541819502316785741383639145866071856825051549231447161710399611381911575660385601546360041084280896676911889810584537683240864405819307049463732925606631546639518426651121208176285007436520251461854127484076350233519219480398658641001242539048046529742114192549782403287806556840860371337966097173350218236381329518702831401361914811597448759832549227759610938548970537888455950617834972888158093407922606309451101643311842471881838667105291086022959240750179576618885386564

I can’t say that I’m anything but impressed. So go on. Reimplement your bank systems in Perl 6 🤪.