New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Floating Point numbers do not roundtrip to string correctly. #16460
Comments
From marco@nethype.deCreated by marco@nethype.deOn my debian 64 bit system with debians perl, perl fails to stringify floating point Note the missing "5" at the end. This is a bug because "1520604616.47292" and "1520604616.472925" get mapped $ perl -e 'die unpack "H*", pack "d", 1520604616.472925' This is a not a problem with floating point itself, as there are distinct string and binary representations $ perl -e 'die unpack "H*", pack "d", 1520604616.472925*2' Therefore I think this is a bug in perl - a floating point number should round trip to string and back Perl Info
|
From @sisyphusLe Fri, 09 Mar 2018 07:21:44 -0800, marco@nethype.de a écrit :
I think it should be fixed, though I'm not so sure that everyone agrees. This is something that has been raised before - eg: Assuming that the floating point type is 'double', the "round trip" will fail for many values if less than 17 decimal digits of precision are used. So ... you go for the 17 digits: $ perl -le 'printf "%.16e\n", 1520604616.472925' and you still end up with something that doesn't match. $ perl -le 'printf "%a\n%a\n", 1520604616.472925, 1.5206046164729249e+09' and it turns out that double is closer to 1.5206046164729249e+09 than it is to 1.520604616472925e+09. Incidentally, in the bug report I linked to above, there's reference to an algorithm by Guy Steele that can be used to avoid such surprises. Cheers, |
The RT System itself - Status changed from 'new' to 'open' |
There's no sign of this ever being fixed, and I don't think there are very many people (apart from me and the OP) who care about it. As a brazen plug, I will mention a couple of extensions that do the roundtrip correctly && do it such that the string contains as few significant decimal digits as possible for the roundtrip to succeed. One is Math::Ryu, which uses the Ryu algorithm (https://github.com/ulfjack/ryu). Math::Ryu's d2s() function works such that, for any double precision NV $d, the condition Examples: Of course, having to do The main problem with Math::Ryu is that it only builds on perls whose nvtype is "double". (If the nvtype is "double" then Math::Ryu should build and install straight out of the box.) If perl's nvtype is not "double" then you'll need to use Math::MPFR's nvtoa() function - again which does the roundtrip using as few significant digits as possible. It uses a "dragon" implementation devised by Steele and White (https://lists.nongnu.org/archive/html/gcl-devel/2012-10/pdfkieTlklRzN.pdf). |
Problem: If we were to simply close this ticket now, in a year or two someone else would stumble on this problem and open a new ticket, probably without searching old tickets. At the very least, we need to document this limitation and perhaps mention some extensions as you do. Can you suggest some appropriate documentation? Of course, if someone thinks this bug is fixable, then we should keep this ticket open. |
I'm not sure that it's actually a "bug", though I may well have referred to it as such, from time to time. I was mainly thinking that this issue could be closed because:
On further reflection, I'm thinking that the behaviour-changing aspect of any action would mean that we cannot do anything about this until perl 7. As regards documentation regarding this issue, I think it would be sufficient to insert into perlnumber.pod a paragraph that states something like:
Maybe place that in the perlnumber documentation under the heading "Decimal Interpolation of Floating Point Values". What do you think ? To be clear - I don't mind at all if this issue remains open. It's just that I perceived there was an opportunity here to reduce the number of open issues by one. |
Migrated from rt.perl.org#132959 (status was 'open')
Searchable as RT132959$
The text was updated successfully, but these errors were encountered: