RE: Floating point exception in strtod()
Dear Corinna, > ...which is what I described in the rest of my mail :) ah, yes, sorry. I stumbled on the "0x96c75d80 which appears to be perfectly valid for a 32 bit int", fell on my nose and looks like I forgot to walk on then. Best regards, Michael Intel Deutschland GmbH Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Christin Eisenschmid, Christian Lamprechter Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928
Re: Floating point exception in strtod()
On Apr 9 14:45, Soegtrop, Michael wrote: > Dear Corinna, > > > 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. > > 2529648000 is a valid unsigned long, but not a valid signed long. The > largest 32 bit long is 2^31-1 = 2147483647. 0x96c75d80 interpreted as > a signed long is a negative number. > > I would say if floating point instructions are used to convert > 2529648000 to a signed 32 bit integer, they should produce an > FE_INVALID exception. ...which is what I described in the rest of my mail :) Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Maintainer cygwin AT cygwin DOT com Red Hat signature.asc Description: PGP signature
RE: Floating point exception in strtod()
Dear Corinna, > 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. 2529648000 is a valid unsigned long, but not a valid signed long. The largest 32 bit long is 2^31-1 = 2147483647. 0x96c75d80 interpreted as a signed long is a negative number. I would say if floating point instructions are used to convert 2529648000 to a signed 32 bit integer, they should produce an FE_INVALID exception. Best regards, Michael Intel Deutschland GmbH Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Christin Eisenschmid, Christian Lamprechter Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928
Re: Floating point exception in strtod()
On Apr 9 08:09, Ken Brown wrote: > On 4/9/2018 5:47 AM, Corinna Vinschen wrote: > > On Apr 7 13:40, Ken Brown wrote: > > > $ cat strtod_test.c > > > #include > > > #include > > > #include > > > > > > int > > > main () > > > { > > >/* The following number comes from /usr/share/asymptote/ode.asy. */ > > >const char *str = "121645100408832000.0"; > > >char *ptr; > > > > > >feenableexcept (FE_INVALID); > > >strtod (str, ); > > > > > >/* 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. > > Thanks for the explanation and the quick fix. I'm sorry for causing > confusion by also sending this to the newlib list. No, that's fine. Actually it belonged to the newlib ML in the first place, so it's good it's in the archives there. Thanks, Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Maintainer cygwin AT cygwin DOT com Red Hat signature.asc Description: PGP signature
Re: Floating point exception in strtod()
On 4/9/2018 5:47 AM, Corinna Vinschen wrote: On Apr 7 13:40, Ken Brown wrote: $ cat strtod_test.c #include #include #include int main () { /* The following number comes from /usr/share/asymptote/ode.asy. */ const char *str = "121645100408832000.0"; char *ptr; feenableexcept (FE_INVALID); strtod (str, ); /* 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. Thanks for the explanation and the quick fix. I'm sorry for causing confusion by also sending this to the newlib list. Ken -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Re: Floating point exception in strtod()
On Apr 7 13:40, Ken Brown wrote: > $ cat strtod_test.c > #include > #include > #include > > int > main () > { > /* The following number comes from /usr/share/asymptote/ode.asy. */ > const char *str = "121645100408832000.0"; > char *ptr; > > feenableexcept (FE_INVALID); > strtod (str, ); > > /* 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 signature.asc Description: PGP signature
RE: Floating point exception in strtod()
> Probably doesn't fit precisely into a double. Does strtold behave > better? actually both numbers can be represented exactly as IEEE double. In Maxima: (%i1) factor(121645100408832000); (%o1) 2^16*3^8*5^3*7^2*11*13*17*19 (%i2) float(log(3^8*5^3*7^2*11*13*17*19)/log(2)); (%o2) 40.75545582601886 (%i3) factor(221645100408832000); (%o3) 2^16*5^3*31*41*1361*15641 (%i4) float(log(5^3*31*41*1361*15641)/log(2)); (%o4) 41.62102908434535 So the first number has 41 bits and the second 42 after removing powers of 2. The significand size of a double is 53 bits (including the implicit 1). Best regards, Michael Intel Deutschland GmbH Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Christin Eisenschmid, Christian Lamprechter Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928
Re: Floating point exception in strtod()
Am 08.04.2018 um 05:11 schrieb Duncan Roe: I tried in 64-bit with the same result as Eliot: works fine w/out feenableexcept, no o/p with feenableexcept. Just in case this may have been overlooked: please note that "no output" actually means the program crashed because of an uncaught SIGFPE, just like the 32-bit version does. The only difference between 32-bit and 64-bit versions of the program is that the 32-bit one outputs the "core dumped" message and writes a stackdump, whereas the 64-bit one just dies without _any_ detectable symptoms: no message, no stackdump file, nothing. -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Re: Floating point exception in strtod()
On Sat, Apr 07, 2018 at 04:56:13PM -0400, Eliot Moss wrote: > On 4/7/2018 1:40 PM, Ken Brown wrote: > > $ cat strtod_test.c > > #include > > #include > > #include > > > > int > > main () > > { > > /* The following number comes from /usr/share/asymptote/ode.asy. */ > > const char *str = "121645100408832000.0"; > > char *ptr; > > > > feenableexcept (FE_INVALID); > > strtod (str, ); > > > > /* If there was an exception, the following will not get executed. */ > > printf ("No exception.\n"); > > } > > If I do the same thing WITHOUT the feenableexcept, it works fine. > Perhaps strtod catches an exception and then applies a different > method in some cases, or perhaps it wants exceptions off and > deals with things its own way. > > If I include the feenableexcept, I get the same behavior you > reported (in 32-bit; I did not test 64-bit). > > Regards - Eliot Moss > I tried in 64-bit with the same result as Eliot: works fine w/out feenableexcept, no o/p with feenableexcept. Cheers ... Duncan. -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Re: Floating point exception in strtod()
On 4/7/2018 1:40 PM, Ken Brown wrote: $ cat strtod_test.c #include #include #include int main () { /* The following number comes from /usr/share/asymptote/ode.asy. */ const char *str = "121645100408832000.0"; char *ptr; feenableexcept (FE_INVALID); strtod (str, ); /* If there was an exception, the following will not get executed. */ printf ("No exception.\n"); } If I do the same thing WITHOUT the feenableexcept, it works fine. Perhaps strtod catches an exception and then applies a different method in some cases, or perhaps it wants exceptions off and deals with things its own way. If I include the feenableexcept, I get the same behavior you reported (in 32-bit; I did not test 64-bit). Regards - Eliot Moss -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Re: Floating point exception in strtod()
Is that 19! ? Probably doesn't fit precisely into a double. Does strtold behave better? Some implementations throw on unrepresentable numbers, e.g. https://docs.oracle.com/cd/E19253-01/816-5168/6mbb3hrte/index.html Ken Brownschrieb am Sa., 7. Apr. 2018, 10:40: > $ cat strtod_test.c > #include > #include > #include > > int > main () > { >/* The following number comes from /usr/share/asymptote/ode.asy. */ >const char *str = "121645100408832000.0"; >char *ptr; > >feenableexcept (FE_INVALID); >strtod (str, ); > >/* 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. > > Ken > > -- > Problem reports: http://cygwin.com/problems.html > FAQ: http://cygwin.com/faq/ > Documentation: http://cygwin.com/docs.html > Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple > > > -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple