-----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;'
3fd3333333333334

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

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.000000000000001e0;'
1

$ perl -E 'say 1.000000000000001e0;'
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.000000000000001e0;'
1.0000000000000011e+000

But that doesn't work on perl6:

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

Is there something amiss here ?

Cheers,
Rob

Reply via email to