develooper Front page | perl.perl6.language | Postings from March 2018

(default) Real->Rat precision should match what compiler uses forliterals

Thread Next
Jim Avera
March 2, 2018 22:34
(default) Real->Rat precision should match what compiler uses forliterals
Message ID:

Using Rakudo 2018.01:

     my Rat  $rat-from-literal = 1.23456789;
     my Rat  $rat-from-str     = "1.23456789".Rat;
     my Real $real             = 1.23456789e0;
     my Rat  $rat-from-real    = $real.Rat;

     say $rat-from-literal.nude; # (123456789 100000000)
     say $rat-from-literal.Str;  # 1.23456789
     say $real.Str;              # 1.23456789
     say $rat-from-str.Str;      # 1.23456789
     say $rat-from-real.Str;     # 1.234568   !?!
     say $rat-from-real.nude;    # (100 81)

 From a user perspective, it's surprising that converting a Real to a 
Rat is by default not as precise as the compiler itself when it converts 
a literal to a Rat.

In particular, if the exact result can be represented in 64 bits (32-bit 
numerator & denom), throwing  away precision when converting from a 
64-bit Real has no obvious practical benefit. That is, throwing away 
precision does not save any memory (assuming Rat uses at least 32+32 -- 
which is just my assumption and might be wrong).

As a programmer,/I//do not want Perl to throw away information without 
express permission/, unless there is a practical necessity to do so, 
such as avoiding exploding memory or computation.


I think the underlying problem is that Real to Rat conversion precision 
is controlled by an "epsilon" value which defaults to 1.0e-6 (see

One could argue with the choice of default, but /there //may not 
exist//an appropriate default/ which always DWIM!

The reason is that I as a programmer don't actually want to limit 
precision /per se; /I only want to limit memory consumed by the result, 
and perhaps the cpu time needed to operate on that result.


A solution might be to instead provide a pragmatic, rather than 
mathematical parameter:

     :$numbits = 64

This would say to keep as much precision as possible while making the 
result fit in 64 bits.   For example 2.147483647e0.Rat would result in 
2147483647/1000000000 instead of 4310/2007.

If a mathematical /epsilon/ is really what some programmers want (I'm 
doubtful), then both options could be provided:

multi methodRat(Real:D:Real$epsilon) # no default, used only if user 
really wants it
multi methodRat(Real:D:Int $maxbits = 64)  # provides the default behavior

I would appreciate any comments/explanations/insight on this topic!


Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About