in reply to Re^2: Determining the minimum representable increment/decrement possible? (Perl's scanf broken?)
in thread Determining the minimum representable increment/decrement possible?

printf "% 25.17g\n", -8.2727285363069939e-293;;
-8.2727285363069883e-293


Yeah, I get the same with mingw-built x64 5.22.0.
This is the perl bug I alluded to in my first post that mis-assigns values by up to a few ULPs.
If you check the hex format (assigned by perl) of -8.2727285363069939e-293 you'll find:
C:\_32>perl -le "print scalar reverse unpack 'h*', pack 'd<', -8.27272 +85363069939e-293;" 834a6aec8f94134c
However, the correct hex format of -8.2727285363069939e-293 is 834a6aec8f941351.
834a6aec8f94134c does in fact correspond to -8.2727285363069883e-293 - so perl is doing the conversion from internal form to decimal string correctly. It's just the initial conversion from decimal string to internal form that was incorrect.

Sadly, no-one seems interested in fixing this - though I think that's because of the degree of difficulty rather than actual "disinterest".
If this level of inaccuracy bothers you (as it does me) then one solution is to assign using POSIX::strtod:
C:\_32>perl -MPOSIX -le "print scalar reverse unpack 'h*', pack 'd<', +POSIX::strtod('-8.2727285363069939e-293');" 834a6aec8f941351 C:\_32>perl -MPOSIX -le "printf '% 25.17g', POSIX::strtod('-8.27272853 +63069939e-293');" -8.2727285363069939e-293
This way you put your faith in the C compiler and that seems to be a safer bet.
(That's probably good enough, though I'd rather put my faith in the mpfr library.)

Cheers,
Rob
  • Comment on Re^3: Determining the minimum representable increment/decrement possible? (Perl's scanf broken?)
  • Select or Download Code

Replies are listed 'Best First'.
Re^4: Determining the minimum representable increment/decrement possible? (Perl's scanf broken?)
by BrowserUk (Patriarch) on Jun 17, 2016 at 14:47 UTC
    Sadly, no-one seems interested in fixing this - though I think that's because of the degree of difficulty rather than actual "disinterest".

    I'm somewhat confused by that. Why not use the underlying CRTs sscanf() or strtod()?

    one solution is to assign using POSIX::strtod

    That's very useful! Thankyou.

    I'd rather put my faith in the mpfr library.

    For the most part, I'm only really using Perl as an interactive calculator for exploring the issues; the actual code is C++; and I'm doing some optimisations in x64 assembler.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.
      Why not use the underlying CRTs sscanf() or strtod()?

      I don't know.
      I speculate that in earlier times those functions were not so reliable and it was decided that perl should do its own implementation.
      I further speculate that it has now got to the stage that unwinding that perl implementation is not a trivial task.

      Cheers,
      Rob

        Grr. I had a notion to try and work out what code Perl was actually using to parse doubles and 'forgot' my rule of the last few years: don't go looking in the recent perl sources; it will only piss you off.

        It pissed me off. It used to be that you could compile Perl to use stdio, and I thought I might do that for 5.22; but apparently that is not longer possible!

        Perl is still my go-to language for getting stuff done in a hurry; and in many cases even when the program has ultimately to be written in some compiled language, whether for speed or to satisfy some other requirement, I still use Perl to prototype and only convert to C or C++ or D or whatever once I have the code working.

        But for the last few years, the P5 development has become introspective, even introverted; titivating instead of innovating; throwing any weird idea that comes up into the code base only to remove it a build or two later. I've lost track of the number of "experimental" additions that have come and inevitably gone.

        It's just a shame that PerlIO isn't so easily back out and discarded! :(


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.

      Why not use the underlying CRTs sscanf() or strtod()?

      I think differences in stringifications of Inf and NaN played a roll.