Re: [perl #132268] Floating point anomalies

2017-10-13 Thread Sisyphus via RT

From: Brandon Allbery
Sent: Friday, October 13, 2017 4:15 AM
To: sisyph...@optusnet.com.au
Cc: Carl Mäsak via RT
Subject: Re: [perl #132268] Floating point anomalies
On Thu, Oct 12, 2017 at 5:31 AM, <sisyph...@optusnet.com.au> wrote:
Perl6's printf() function looks a little suspect - though I might be missing
something here.

>> As with perl5's say function, doubles are rounded to 14 decimal digits of 
>> precision

To correct that assertion, they both of course round to 15 decimal digits of 
precision.

> I question your use of 'accurate'. The low bits are *never* accurate. 
> They're trying to be more 'precise', but the value they have will depend 
> strongly on how exactly the value was calculated, and there are entirely 
> reasonable design decisions that can cause them to differ between 
> implementations.

I don't think there's anything "reasonable" about a printf() implementation 
that tells me:

$ perl6 -e 'printf "%.16e\n", Num(sqrt(3e0));'
1.7320508075688800e+00

Perl6 knows quite well that a double assigned a value of 
1.7320508075688800e+00 is not equivalent to the double returned by 
Num(sqrt(3e0)) :

$ perl6 -e 'say "not equivalent" if 1.7320508075688800e0 != Num(sqrt(3e0));'
not equivalent

Furthermore, perl6 also knows quite well that a double assigned the value 
1.7320508075688772e+00 *is* equivalent to the double returned by 
Num(sqrt(3e0)):

$ perl6 -e 'say "ok" if 1.7320508075688772e0 == Num(sqrt(3e0));'
ok

It's bad enough that perl5 and perl6 round to 15 decimal digits of 
precision, but at least perl5's printf will give me 17 decimal digits when I 
ask it to (and I think perl6 should do the same):

$ perl -e 'printf "%.16e\n", sqrt(3.0);'
1.7320508075688772e+00

As a feature request, it would also be nice to see "%a" formatting 
implemented as that then provides one with the means to see the exact value 
of the given double.

Cheers,
Rob 


Re: [perl #132268] Floating point anomalies

2017-10-13 Thread Brandon Allbery via RT
On Fri, Oct 13, 2017 at 4:59 AM,  wrote:

> It's bad enough that perl5 and perl6 round to 15 decimal digits of
> precision, but at least perl5's printf will give me 17 decimal digits when
> I ask it to (and I think perl6 should do the same):
>

I am wondering if youve talked to any Intel FP engineers. 17 decimal digits
sounds like you expect full internal 80-bit precision even if it's not in
an internal register. Good luck.
(gcc does have ways of doing this on sufficiently recent processors. msvc
does NOT. So, you've just demanded a Windows vs. Unix difference be
enshrined in the language?)

-- 
brandon s allbery kf8nh   sine nomine associates
allber...@gmail.com  ballb...@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonadhttp://sinenomine.net


Re: [perl #132268] Floating point anomalies

2017-10-13 Thread Brandon Allbery
On Fri, Oct 13, 2017 at 4:59 AM,  wrote:

> It's bad enough that perl5 and perl6 round to 15 decimal digits of
> precision, but at least perl5's printf will give me 17 decimal digits when
> I ask it to (and I think perl6 should do the same):
>

I am wondering if youve talked to any Intel FP engineers. 17 decimal digits
sounds like you expect full internal 80-bit precision even if it's not in
an internal register. Good luck.
(gcc does have ways of doing this on sufficiently recent processors. msvc
does NOT. So, you've just demanded a Windows vs. Unix difference be
enshrined in the language?)

-- 
brandon s allbery kf8nh   sine nomine associates
allber...@gmail.com  ballb...@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonadhttp://sinenomine.net


Re: [perl #132268] Floating point anomalies

2017-10-13 Thread sisyphus1


From: Brandon Allbery
Sent: Friday, October 13, 2017 4:15 AM
To: sisyph...@optusnet.com.au
Cc: Carl Mäsak via RT
Subject: Re: [perl #132268] Floating point anomalies
On Thu, Oct 12, 2017 at 5:31 AM, <sisyph...@optusnet.com.au> wrote:
Perl6's printf() function looks a little suspect - though I might be missing
something here.

As with perl5's say function, doubles are rounded to 14 decimal digits of 
precision


To correct that assertion, they both of course round to 15 decimal digits of 
precision.


I question your use of 'accurate'. The low bits are *never* accurate. 
They're trying to be more 'precise', but the value they have will depend 
strongly on how exactly the value was calculated, and there are entirely 
reasonable design decisions that can cause them to differ between 
implementations.


I don't think there's anything "reasonable" about a printf() implementation 
that tells me:


$ perl6 -e 'printf "%.16e\n", Num(sqrt(3e0));'
1.7320508075688800e+00

Perl6 knows quite well that a double assigned a value of 
1.7320508075688800e+00 is not equivalent to the double returned by 
Num(sqrt(3e0)) :


$ perl6 -e 'say "not equivalent" if 1.7320508075688800e0 != Num(sqrt(3e0));'
not equivalent

Furthermore, perl6 also knows quite well that a double assigned the value 
1.7320508075688772e+00 *is* equivalent to the double returned by 
Num(sqrt(3e0)):


$ perl6 -e 'say "ok" if 1.7320508075688772e0 == Num(sqrt(3e0));'
ok

It's bad enough that perl5 and perl6 round to 15 decimal digits of 
precision, but at least perl5's printf will give me 17 decimal digits when I 
ask it to (and I think perl6 should do the same):


$ perl -e 'printf "%.16e\n", sqrt(3.0);'
1.7320508075688772e+00

As a feature request, it would also be nice to see "%a" formatting 
implemented as that then provides one with the means to see the exact value 
of the given double.


Cheers,
Rob 


Re: [perl #132268] Floating point anomalies

2017-10-13 Thread Sisyphus via RT
-Original Message- 
From: Zoffix Znet via RT
Sent: Wednesday, October 11, 2017 11:09 PM
To: sisyph...@optusnet.com.au
Subject: [perl #132268] Floating point anomalies

> What you describe looks to be similar to the other issue I have in my
> private bug stash:
>
>say  .1e0  +  .2e0  ==  .3e0;  # False
>say 1.0e-1 + 2.0e-1 == 3.0e-1; # True;
>
> And a brief look into guts suggests it's to do with the way our Nums are
> constructed during parsing. I was able to repro the issue with the C
> version of what we do in our Grammar: https://glot.io/snippets/eufyogt02g

Yes, the anomaly with those particular values lies in the assignment of .3e0
versus the assignment of 3.0e-1.
Looks like it's the difference between calculating 3 * 0.1 and 30 * 0.01:

$ perl -le 'print scalar reverse unpack "h*", pack "d<", 3 * 0.1;'
3fd4

$ perl -le 'print scalar reverse unpack "h*", pack "d<", 30 * 0.01;'
3fd3

At least, the calculation of 3.0e-1 produces produces the first value (which
is overstated by one ULP), and the calculation of 0.3e0 produces the second
(which is correct).


> So yeah, the plan is to eventually address these.

That's good news.

> If you spot any more inconsistencies and weirdness, please report them.

Perl6's printf() function looks a little suspect - though I might be missing
something here.

As with perl5's say function, doubles are rounded to 14 decimal digits of
precision, so we get:

$ perl6 -e 'say 1.001e0;'
1

$ perl -E 'say 1.001e0;'
1

On perl5 we can get to see a more accurate rendition of the base 10 value
using printf():

$ perl -e 'printf "%.16e\n", 1.001e0;'
1.0011e+000

But that doesn't work on perl6:

$ perl6 -e 'printf "%.16e\n", 1.001e0;'
1.e+00

Is there something amiss here ?

Cheers,
Rob


Re: [perl #132268] Floating point anomalies

2017-10-12 Thread Brandon Allbery via RT
On Thu, Oct 12, 2017 at 5:31 AM,  wrote:

> Perl6's printf() function looks a little suspect - though I might be
> missing
> something here.
>
> As with perl5's say function, doubles are rounded to 14 decimal digits of
> precision, so we get:
>
> $ perl6 -e 'say 1.001e0;'
> 1
>
> $ perl -E 'say 1.001e0;'
> 1
>
> On perl5 we can get to see a more accurate rendition of the base 10 value
>

I question your use of 'accurate'. The low bits are *never* accurate.
They're trying to be more 'precise', but the value they have will depend
strongly on how exactly the value was calculated, and there are entirely
reasonable design decisions that can cause them to differ between
implementations.

-- 
brandon s allbery kf8nh   sine nomine associates
allber...@gmail.com  ballb...@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonadhttp://sinenomine.net


Re: [perl #132268] Floating point anomalies

2017-10-12 Thread Brandon Allbery
On Thu, Oct 12, 2017 at 5:31 AM,  wrote:

> Perl6's printf() function looks a little suspect - though I might be
> missing
> something here.
>
> As with perl5's say function, doubles are rounded to 14 decimal digits of
> precision, so we get:
>
> $ perl6 -e 'say 1.001e0;'
> 1
>
> $ perl -E 'say 1.001e0;'
> 1
>
> On perl5 we can get to see a more accurate rendition of the base 10 value
>

I question your use of 'accurate'. The low bits are *never* accurate.
They're trying to be more 'precise', but the value they have will depend
strongly on how exactly the value was calculated, and there are entirely
reasonable design decisions that can cause them to differ between
implementations.

-- 
brandon s allbery kf8nh   sine nomine associates
allber...@gmail.com  ballb...@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonadhttp://sinenomine.net


Re: [perl #132268] Floating point anomalies

2017-10-12 Thread sisyphus1
-Original Message- 
From: Zoffix Znet via RT

Sent: Wednesday, October 11, 2017 11:09 PM
To: sisyph...@optusnet.com.au
Subject: [perl #132268] Floating point anomalies


What you describe looks to be similar to the other issue I have in my
private bug stash:

   say  .1e0  +  .2e0  ==  .3e0;  # False
   say 1.0e-1 + 2.0e-1 == 3.0e-1; # True;

And a brief look into guts suggests it's to do with the way our Nums are
constructed during parsing. I was able to repro the issue with the C
version of what we do in our Grammar: https://glot.io/snippets/eufyogt02g


Yes, the anomaly with those particular values lies in the assignment of .3e0
versus the assignment of 3.0e-1.
Looks like it's the difference between calculating 3 * 0.1 and 30 * 0.01:

$ perl -le 'print scalar reverse unpack "h*", pack "d<", 3 * 0.1;'
3fd4

$ perl -le 'print scalar reverse unpack "h*", pack "d<", 30 * 0.01;'
3fd3

At least, the calculation of 3.0e-1 produces produces the first value (which
is overstated by one ULP), and the calculation of 0.3e0 produces the second
(which is correct).



So yeah, the plan is to eventually address these.


That's good news.


If you spot any more inconsistencies and weirdness, please report them.


Perl6's printf() function looks a little suspect - though I might be missing
something here.

As with perl5's say function, doubles are rounded to 14 decimal digits of
precision, so we get:

$ perl6 -e 'say 1.001e0;'
1

$ perl -E 'say 1.001e0;'
1

On perl5 we can get to see a more accurate rendition of the base 10 value
using printf():

$ perl -e 'printf "%.16e\n", 1.001e0;'
1.0011e+000

But that doesn't work on perl6:

$ perl6 -e 'printf "%.16e\n", 1.001e0;'
1.e+00

Is there something amiss here ?

Cheers,
Rob