Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Small Perl 6 discoveries III, Ints

by Anonymous Monk
on Sep 28, 2017 at 22:47 UTC ( #1200326=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Anybody want to try and explain this one?
> Int(2e25) 20000000000000001811939328 > Int(20e24) 19999999999999997516972032 > (Int(2e25), Int(20e24)) (20000000000000001811939328 20000000000000001811939328) > (Int(20e24), Int(2e25)) (19999999999999997516972032 19999999999999997516972032)

Replies are listed 'Best First'.
Re: Small Perl 6 discoveries III, Ints
by syphilis (Bishop) on Sep 28, 2017 at 23:46 UTC
    Anybody want to try and explain this one?

    I find this is a bit interesting.
    I can reproduce it on perl-5.26.0 (nvtype=double):
    C:\>perl -le "printf '%.0f', 2e25;" 20000000000000001811939328 C:\>perl -le "printf '%.0f', 20e24;" 19999999999999997516972032
    It happens because 20e24 is miscalculated (off by one ULP). It's an error that doesn't occur on all of my "double" perls. For example, my perl-5.16.0 is not subject to this issue.

    UPDATE: Actually, it occurs on all of my "double" builds of perl that were built using an x86_64 compiler.
    I also see the same bug on perl-5.26.0 on Linux (Ubuntu):
    $ perl -le 'printf "%.0f\n", 2e25;' 20000000000000001811939328 $ perl -le "printf '%.0f', 20e24;" 19999999999999997516972032

    Odd that perl6 should have managed to inherit the same failing.
    Are you using a current version of perl6 ?

    Cheers,
    Rob
      Rakudo star 2017.07. It's the third and fourth lines that have me scratching my head, though.
Re: Small Perl 6 discoveries III, Ints
by holli (Abbot) on Sep 29, 2017 at 05:50 UTC
    The exponential notation always produces a Num (and therefore introduces rounding errors), even when a value could be expressed as a Rat. This is by design as I have been told. It works correctly though if you do this:
    > 2*(10**25) 20000000000000000000000000 > 20*(10**24) 20000000000000000000000000 > 2*(10**25) == 20*(10**24) True


    holli

    You can lead your users to water, but alas, you cannot drown them.
      Yes, thanks. We've discovered that the Int is actually working correctly in this case, but the Num is broken.
        It's not broken. It's just a floating point number.


        holli

        You can lead your users to water, but alas, you cannot drown them.
Re: Small Perl 6 discoveries III, Ints
by virtualsue (Vicar) on Sep 29, 2017 at 14:57 UTC

    The code for Perl 6 Rakudo is on github and there is an up-to-date document on how to report bugs in it on the github project wiki just in case anyone feels like getting more involved.

    Rakudo codebase Rakudo bug tracking
      ... there is an up-to-date document on how to report bugs in it on the github project wiki just in case anyone feels like getting more involved

      Not that I really wanted to get involved, but I was a little curious about the status of some of the issues raised in this thread.

      So, last night, I submitted a bug report that referred to 2 of the issues raised here:
      1) that perl6 evaluates '1.000000000000001e0 == 1e0' as true;
      2) that perl6 produces different outputs for 'Int(2e25)' and 'Int(20e24)'.

      Turns out that the second is the result of a known issue with perl6's way of constructing Nums ... not so sure that the first one is exactly the same issue.
      Anyway, Zoffix Znet's reply to the bug report informs us that these bugs will be fixed, though it's presently not all that high on the list of priorities.

      Seems that perl6 assigns 2e25 as 2 * 1e25, but assigns 20e24 as 20 * 1e24. Hence the discrepancy.

      Cheers,
      Rob
        The problem can be summarized as follows:
        • Some platforms ship with a vendor-supplied libc that's really sloppy.
        • Because of this, perl5 development has been slowly replacing use of libc with home-grown code.
        • However, GNU libc is really good. It's the default libc on many platforms, and it's available on most.
        • As a result, many perl programmers have been experiencing slowly deteriorating quality of numeric implementation for around two decades. Perl6 accelerates this trend.
      Be my guest. IDGAF, and the perl6 developers obviously don't either. My entire qualification with Perl6 is that I've read the first three chapters of Perl 6 Deep Dive and kicked it around a little bit in my spare time. Everywhere I look, I see bugs.

        Oh, that's so cute. AM even provided a link to an explanation for 'IDGAF'.

        I had already assumed that the anonymous coward who started this thread wouldn't be interested in what I wrote. I was talking to other people who might happen to see the thread.

        A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Small Perl 6 discoveries III, Ints
by Anonymous Monk on Sep 29, 2017 at 01:41 UTC
    Well, mystery sort of solved. It seems to be some kind of misguided parser optimization. It will reuse a floating-point literal for another value that's approximately equal.
    > my $a = 2e25; my $b = 20e24; $a - $b 0 > (Int($a), $a.WHERE) (20000000000000001811939328 4431024856) > (Int($b), $b.WHERE) (20000000000000001811939328 4431024856) > my $c = Num('2e25'); my $d = Num('20e24'); $c - $d 4294967296 > (Int($c), $c.WHERE) (20000000000000001811939328 4431025568) > (Int($d), $d.WHERE) (19999999999999997516972032 4431025664)
    Observe that $a and $b refer to the same object (they have the same address), while $c and $d are distinct.
      It will reuse a floating-point literal for another value that's approximately equal

      I'll speculate that it will only engage in "reuse" when the two values are exactly equal. (Bear in mind that 2e25 and 20e24 are exactly equal.)
      So it should be a valid optimization - it's only being brought undone by the miscalculation of 20e24.

      The miscalculation of 20e24 is a bug in perl6 that should be reported, though FAIK it might already have been fixed.

      UPDATE: The same miscalculation is also a bug in perl5 - but such miscalculations are already known in perl 5

      Cheers,
      Rob
        > 1.000000000000001e0 - 1e0 0 > 1.000000000000001e0 - 1 1.11022302462516e-15

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1200326]
Approved by beech
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (4)
As of 2020-11-30 02:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?