Re: (default) Real->Rat precision should match what compiler uses for literals

[email protected] (yary) Sun, 4 Mar 2018 10:49:01 -0300
Newsgroups perl.perl6.language
Message-ID <CAG2CFAaA1nur8Lk+dr1ChAzSxJJEx0zeY_9Y+zcTOav90iBASA@mail.gmail.com>
--000000000000121de30566967a94
Content-Type: text/plain; charset="UTF-8"

The point of Rats is making Perl6 more correct and less surprising in
common cases, such as
$ perl6
> 1.1+2.2
3.3
> 1.1+2.2 == 3.3
True
> 1.1+2.2 != 3.3
False

vs any language using binary floating-point arithmetic

  DB<1> p 1.1+2.2
3.3
  DB<2> p 1.1+2.2 == 3.3

  DB<3> p 1.1+2.2 != 3.3
1

In that spirit, I'd expect numeric comparison in general, and epsilon
specifically, to be set so these return True:

> pi == pi.Rat # Does Num to Rat conversion keep its precision?
False
> pi.Str.Num == pi # Does Num survive string round-trip? - Nothing to do
with epsilon
False

On the other hand, the original poster Jim and I are both fiddling with the
language to see what it's doing with conversions- I'm are not coming across
this in an application.

What's the greatest value of epsilon that guarantees $x == $x.Rat for all
Num $x - and does that epsilon make denominators that are "too big?" My
understanding of floating point suggests that we should have an epsilon of
1/2**(mantissa bits-1). On a 64-bit platform that's 1/2**52 - for a 32-bit
float that's 1/2**23. Using a 64-bit Rakudo:

> pi.Rat(1/2**52) == pi  # Just enough precision to match this platform's
Num
True
> pi.Rat(1/2**51) == pi  # Epsilon falling a bit short for precision
False

In terms of correctness, epsilon=1/2**(mantissa bits-1) looks like a
winner. Is that acceptable for size and speed?

and digressing, how to make "pi.Str.Num == pi" True?

--000000000000121de30566967a94
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div><div>The point of Rats is making Perl6 more corr=
ect and less surprising in common cases, such as<br><div style=3D"margin-le=
ft:40px">$ perl6<br>&gt; 1.1+2.2<br>3.3<br>&gt; 1.1+2.2 =3D=3D 3.3<br>True<=
br>&gt; 1.1+2.2 !=3D 3.3<br>False<br></div><br></div>vs any language using =
binary floating-point arithmetic<br><br><div style=3D"margin-left:40px">=C2=
=A0 DB&lt;1&gt; p 1.1+2.2<br>3.3<br>=C2=A0 DB&lt;2&gt; p 1.1+2.2 =3D=3D 3.3=
<br><br>=C2=A0 DB&lt;3&gt; p 1.1+2.2 !=3D 3.3<br>1<br></div><br></div>In th=
at spirit, I&#39;d expect numeric comparison in general, and epsilon specif=
ically, to be set so these return True:<br><br>&gt; pi =3D=3D pi.Rat # Does=
 Num to Rat conversion keep its precision?<br>False<br>&gt; pi.Str.Num =3D=
=3D pi # Does Num survive string round-trip? - Nothing to do with epsilon<b=
r>False<br><br></div>On the other hand, the original poster Jim and I are b=
oth fiddling with the language to see what it&#39;s doing with conversions-=
 I&#39;m are not coming across this in an application.<br><div><br></div><d=
iv>What&#39;s the greatest value of epsilon that guarantees $x =3D=3D $x.Ra=
t for all Num $x - and does that epsilon make denominators that are &quot;t=
oo big?&quot; My understanding of floating point suggests that we should ha=
ve an epsilon of 1/2**(mantissa bits-1). On a 64-bit platform that&#39;s 1/=
2**52 - for a 32-bit float that&#39;s 1/2**23. Using a 64-bit Rakudo:<br><b=
r>&gt; pi.Rat(1/2**52) =3D=3D pi=C2=A0 # Just enough precision to match thi=
s platform&#39;s Num<br>True<br>&gt; pi.Rat(1/2**51) =3D=3D pi=C2=A0 # Epsi=
lon falling a bit short for precision<br>False<br><br></div><div>In terms o=
f correctness, epsilon=3D1/2**(mantissa bits-1) looks like a winner. Is tha=
t acceptable for size and speed?<br><br></div><div>and digressing, how to m=
ake &quot;pi.Str.Num =3D=3D pi&quot; True?<br></div></div>

--000000000000121de30566967a94--