[Bug libc/26137] New: strtod() triggers exception FE_INEXACT on reasonable input

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[Bug libc/26137] New: strtod() triggers exception FE_INEXACT on reasonable input

Sourceware - glibc-bugs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26137

            Bug ID: 26137
           Summary: strtod() triggers exception FE_INEXACT on reasonable
                    input
           Product: glibc
           Version: 2.33
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libc
          Assignee: unassigned at sourceware dot org
          Reporter: dclarke at blastwave dot org
                CC: drepper.fsp at gmail dot com
  Target Milestone: ---

May be related to 1750.

Plenty of details about how this was hit at :

    https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=247370

However on 32-bit Linux systems they all triggered a FE_INEXACT strangely
for input 1 + 2^(-32) = 1.000000000232830643653869628906250 which is
perfectly reasonable and all other reasonable ( and trivial ) test cases
are fine. See test code in that FreeBSD bug report as well as a tarball
with a test script. Here is a snippit from a Debian sid i686 server :

.
.
.
---- 31 ----
1.0000000004656612873077392578125000000000000000000000000000000000
-------------------------------------------------------------
           system name = Linux
             node name = mars
               release = 5.8.0-rc1-genunix
               version = #1 SMP Mon Jun 15 04:57:18 UTC 2020
               machine = i686
             page size = 4096
          avail memory = 782237696
                       = 763904 kB
                       = 746 MB
                endian = little endian
 sizeof(unsigned long) = 4
           sizeof(int) = 4
         sizeof(void*) = 4
     fp rounding mode is FE_TONEAREST
-------------------------------------------------------------
INFO : seems like a decimal number +1.0000000004656612873077392578125  

---- 32 ----
1.0000000002328306436538696289062500000000000000000000000000000000
-------------------------------------------------------------
           system name = Linux
             node name = mars
               release = 5.8.0-rc1-genunix
               version = #1 SMP Mon Jun 15 04:57:18 UTC 2020
               machine = i686
             page size = 4096
          avail memory = 782237696
                       = 763904 kB
                       = 746 MB
                endian = little endian
 sizeof(unsigned long) = 4
           sizeof(int) = 4
         sizeof(void*) = 4
     fp rounding mode is FE_TONEAREST
-------------------------------------------------------------
INFO : FP Exception raised is FE_INEXACT
WARN : FE_INEXACT returned by strtod()
INFO : seems like a decimal number +1.00000000023283064365386962890625

---- 33 ----
1.0000000001164153218269348144531250000000000000000000000000000000
-------------------------------------------------------------
           system name = Linux
             node name = mars
               release = 5.8.0-rc1-genunix
               version = #1 SMP Mon Jun 15 04:57:18 UTC 2020
               machine = i686
             page size = 4096
          avail memory = 782237696
                       = 763904 kB
                       = 746 MB
                endian = little endian
 sizeof(unsigned long) = 4
           sizeof(int) = 4
         sizeof(void*) = 4
     fp rounding mode is FE_TONEAREST
-------------------------------------------------------------
INFO : seems like a decimal number +1.000000000116415321826934814453125
.
.
.

There you see that 1+2^(-31) is fine as well as 1+2^(-33) however the
test in the middle for 1+2^(-32) triggers exception FE_INEXACT. Very
strange.

Same results on Kali Linux based on the armv7l architecture as well
as even Debian sid on a VIA Eden Esther processor. Every reasonable
variation of 1 + 2^( -n ) for n from 1 to 52 is perfect with the
exception ( pun intended ) of n=32.  Also for n>52 we see reasonable
FE_INEXACT.

I have not yet singled stepped may way through to see what is odd
about n=32 but figured I could open a bug report.


--
Dennis Clarke
RISC-V/SPARC/PPC/ARM/CISC
UNIX and Linux spoken
GreyBeard and suspenders optional

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug libc/26137] strtod() triggers exception FE_INEXACT on reasonable input

Sourceware - glibc-bugs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26137

--- Comment #1 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Joseph Myers <[hidden email]>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=09555b9721d090f7917f8221be2613a4d6a9b0f6

commit 09555b9721d090f7917f8221be2613a4d6a9b0f6
Author: Joseph Myers <[hidden email]>
Date:   Tue Jun 30 23:04:06 2020 +0000

    Fix strtod multiple-precision division bug (bug 26137).

    Bug 26137 reports spurious "inexact" exceptions from strtod, on 32-bit
    systems only, for a decimal argument that is exactly 1 + 2^-32.  In
    fact the same issue also appears for 1 + 2^-64 and 1 + 2^-96 as
    arguments to strtof128 on 32-bit systems, and 1 + 2^-64 as an argument
    to strtof128 on 64-bit systems.  In FE_DOWNWARD or FE_TOWARDZERO mode,
    the return value is also incorrect.

    The problem is in the multiple-precision division logic used in the
    case of dividing by a denominator that occupies at least three GMP
    limbs.  There was a comment "The division does not work if the upper
    limb of the two-limb mumerator is greater than the denominator.", but
    in fact there were problems for the case of equality (that is, where
    the high limbs are equal, offset by some multiple of the GMP limb
    size) as well.  In such cases, the code used "quot = ~(mp_limb_t) 0;"
    (with subsequent correction if that is an overestimate), because
    udiv_qrnnd does not support the case of equality, but it's possible
    for the shifted numerator to be greater than or equal to the
    denominator, in which case that is an underestimate.  To avoid that,
    this patch changes the ">" condition to ">=", meaning the first
    division is done with a zero high word.

    The tests added are all 1 + 2^-n for n from 1 to 113 except for those
    that were already present in tst-strtod-round-data.

    Tested for x86_64 and x86.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug libc/26137] strtod() triggers exception FE_INEXACT on reasonable input

Sourceware - glibc-bugs mailing list
In reply to this post by Sourceware - glibc-bugs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26137

Joseph Myers <jsm28 at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|UNCONFIRMED                 |RESOLVED
   Target Milestone|---                         |2.32

--- Comment #2 from Joseph Myers <jsm28 at gcc dot gnu.org> ---
Fixed for 2.32.

--
You are receiving this mail because:
You are on the CC list for the bug.
Reply | Threaded
Open this post in threaded view
|

[Bug libc/26137] strtod() triggers exception FE_INEXACT on reasonable input

Sourceware - glibc-bugs mailing list
In reply to this post by Sourceware - glibc-bugs mailing list
https://sourceware.org/bugzilla/show_bug.cgi?id=26137

--- Comment #3 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Joseph Myers <[hidden email]>:

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c6aac3bf3663709cdefde5f5d5e9e875d607be5e

commit c6aac3bf3663709cdefde5f5d5e9e875d607be5e
Author: Joseph Myers <[hidden email]>
Date:   Wed Jul 1 14:53:30 2020 +0000

    Fix typo in comment in bug 26137 fix.

--
You are receiving this mail because:
You are on the CC list for the bug.