Floating point exception in strtod()

Corinna Vinschen corinna-cygwin@cygwin.com
Mon Apr 9 09:47:00 GMT 2018


On Apr  7 13:40, Ken Brown wrote:
> $ cat strtod_test.c
> #include <stdio.h>
> #include <stdlib.h>
> #include <fenv.h>
> 
> int
> main ()
> {
>   /* The following number comes from /usr/share/asymptote/ode.asy.  */
>   const char *str = "121645100408832000.0";
>   char *ptr;
> 
>   feenableexcept (FE_INVALID);
>   strtod (str, &ptr);
> 
>   /* If there was an exception, the following will not get executed.  */
>   printf ("No exception.\n");
> }
> 
> $ gcc strtod_test.c
> 
> $ ./a
> Floating point exception (core dumped)
> 
> [The above was on x86.  On x86_64 there's simply no output.]
> 
> I have no idea what's special about the number 121645100408832000.0, but the
> problem goes away if, for example, I replace the leading 1 by 2.

GDB shows that the exception occurs in newlib/libc/stdlib/strtod.c
line 1189, in this statment, which looks rather inconspicious at
first glance:

   L = (Long)aadj;

L is of type Long == int32_t, aadj is of type double.  The
value of aadj at this time is 2529648000.0 == 0x96c75d80 which
appears to be perfectly valid for a 32 bit int.

However, on 64 bit for example the assembler statement generating the FP
exception is

  cvttsd2si %xmm0,%eax

It is documented that this statemnt may raise FE_INVALID or FE_INEXACT
exceptions.  The problem is that the generated 32 bit value is a
negative signed int value, while the source operand is positive.  So the
conversion is, in fact, invalid.

I applied a fix to newlib's strtod, to always use 64 bit ints in this
place.  This fixes the problem and no exception is raised.

I'm just generating new developer snapshots.  They should be available
in half an hour or so on https://cygwin.com/snapshots/

FTR, the somewhat more complex strtold implementation is not affected.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20180409/80fba6d1/attachment.sig>


More information about the Cygwin mailing list