* Floating point exception in strtod() @ 2018-04-07 17:40 Ken Brown 2018-04-07 20:52 ` Dan Kegel ` (2 more replies) 0 siblings, 3 replies; 12+ messages in thread From: Ken Brown @ 2018-04-07 17:40 UTC (permalink / raw) To: cygwin $ 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. 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Floating point exception in strtod() 2018-04-07 17:40 Floating point exception in strtod() Ken Brown @ 2018-04-07 20:52 ` Dan Kegel 2018-04-08 12:57 ` Soegtrop, Michael 2018-04-07 20:56 ` Eliot Moss 2018-04-09 9:47 ` Corinna Vinschen 2 siblings, 1 reply; 12+ messages in thread From: Dan Kegel @ 2018-04-07 20:52 UTC (permalink / raw) To: cygwin 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 Brown <kbrown@cornell.edu> schrieb am Sa., 7. Apr. 2018, 10:40: > $ 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. > > 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Floating point exception in strtod() 2018-04-07 20:52 ` Dan Kegel @ 2018-04-08 12:57 ` Soegtrop, Michael 0 siblings, 0 replies; 12+ messages in thread From: Soegtrop, Michael @ 2018-04-08 12:57 UTC (permalink / raw) To: dank, cygwin [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset="utf-8", Size: 1175 bytes --] > 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 \x03BKCB\x1cØ\x19[H\x1c\^[Ü\x1cÎ\b\b\b\b\b\b\x1a\x1d\x1d\x1c\x0eËØÞYÝÚ[ÛÛKÜ\x1cØ\x19[\Ë\x1d^[[\x03BTN\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\x1a\x1d\x1d\x1c\x0eËØÞYÝÚ[ÛÛKÙ\KÃB^[ØÝ[Y[\x18]\x1a[Û\b\b\b\b\b\b\b\b\x1a\x1d\x1d\x1c\x0eËØÞYÝÚ[ÛÛKÙ^[ØÜË\x1d^[[\x03B[ÝXØÜXH\x1a[Î\b\b\b\b\b\x1a\x1d\x1d\x1c\x0eËØÞYÝÚ[ÛÛKÛ[\vÈÝ[ÝXØÜXK\Ú[\^[\x19CBB ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Floating point exception in strtod() 2018-04-07 17:40 Floating point exception in strtod() Ken Brown 2018-04-07 20:52 ` Dan Kegel @ 2018-04-07 20:56 ` Eliot Moss 2018-04-08 3:12 ` Duncan Roe 2018-04-09 9:47 ` Corinna Vinschen 2 siblings, 1 reply; 12+ messages in thread From: Eliot Moss @ 2018-04-07 20:56 UTC (permalink / raw) To: cygwin On 4/7/2018 1:40 PM, 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"); > } 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Floating point exception in strtod() 2018-04-07 20:56 ` Eliot Moss @ 2018-04-08 3:12 ` Duncan Roe 2018-04-08 10:25 ` Hans-Bernhard Bröker 0 siblings, 1 reply; 12+ messages in thread From: Duncan Roe @ 2018-04-08 3:12 UTC (permalink / raw) To: cygwin 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 <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"); > > } > > 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Floating point exception in strtod() 2018-04-08 3:12 ` Duncan Roe @ 2018-04-08 10:25 ` Hans-Bernhard Bröker 0 siblings, 0 replies; 12+ messages in thread From: Hans-Bernhard Bröker @ 2018-04-08 10:25 UTC (permalink / raw) To: cygwin 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Floating point exception in strtod() 2018-04-07 17:40 Floating point exception in strtod() Ken Brown 2018-04-07 20:52 ` Dan Kegel 2018-04-07 20:56 ` Eliot Moss @ 2018-04-09 9:47 ` Corinna Vinschen 2018-04-09 12:09 ` Ken Brown 2018-04-09 14:46 ` Soegtrop, Michael 2 siblings, 2 replies; 12+ messages in thread From: Corinna Vinschen @ 2018-04-09 9:47 UTC (permalink / raw) To: cygwin [-- Attachment #1: Type: text/plain, Size: 1983 bytes --] 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 [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Floating point exception in strtod() 2018-04-09 9:47 ` Corinna Vinschen @ 2018-04-09 12:09 ` Ken Brown 2018-04-09 12:51 ` Corinna Vinschen 2018-04-09 14:46 ` Soegtrop, Michael 1 sibling, 1 reply; 12+ messages in thread From: Ken Brown @ 2018-04-09 12:09 UTC (permalink / raw) To: cygwin On 4/9/2018 5:47 AM, Corinna Vinschen wrote: > 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. 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Floating point exception in strtod() 2018-04-09 12:09 ` Ken Brown @ 2018-04-09 12:51 ` Corinna Vinschen 0 siblings, 0 replies; 12+ messages in thread From: Corinna Vinschen @ 2018-04-09 12:51 UTC (permalink / raw) To: cygwin [-- Attachment #1: Type: text/plain, Size: 2339 bytes --] 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 <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. > > 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 [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Floating point exception in strtod() 2018-04-09 9:47 ` Corinna Vinschen 2018-04-09 12:09 ` Ken Brown @ 2018-04-09 14:46 ` Soegtrop, Michael 2018-04-09 15:33 ` Corinna Vinschen 1 sibling, 1 reply; 12+ messages in thread From: Soegtrop, Michael @ 2018-04-09 14:46 UTC (permalink / raw) To: cygwin [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset="utf-8", Size: 1090 bytes --] 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 \0ТÒÐÐ¥\a&ö&ÆVÒ\a&W\x06÷'G3¢\x02\x02\x02\x02\x02\x02\x06GG\x03¢òö7wvâæ6öÒ÷\a&ö&ÆV×2æFÖÀФd\x15\x13¢\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x06GG\x03¢òö7wvâæ6öÒöf\x17\x12ðФFö7VÖVçF\x17Föã¢\x02\x02\x02\x02\x02\x02\x02\x02\x06GG\x03¢òö7wvâæ6öÒöFö72æFÖÀÐ¥Vç7V'67&&R\x06æfó¢\x02\x02\x02\x02\x02\x06GG\x03¢òö7wvâæ6öÒöÖÂò7Vç7V'67&&R×6×\x06ÆPÐ Ð ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Floating point exception in strtod() 2018-04-09 14:46 ` Soegtrop, Michael @ 2018-04-09 15:33 ` Corinna Vinschen 2018-04-09 15:55 ` Soegtrop, Michael 0 siblings, 1 reply; 12+ messages in thread From: Corinna Vinschen @ 2018-04-09 15:33 UTC (permalink / raw) To: cygwin [-- Attachment #1: Type: text/plain, Size: 819 bytes --] 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 [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: Floating point exception in strtod() 2018-04-09 15:33 ` Corinna Vinschen @ 2018-04-09 15:55 ` Soegtrop, Michael 0 siblings, 0 replies; 12+ messages in thread From: Soegtrop, Michael @ 2018-04-09 15:55 UTC (permalink / raw) To: cygwin [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset="utf-8", Size: 806 bytes --] 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 \x03BKCB\x1cØ\x19[H\x1c\^[Ü\x1cÎ\b\b\b\b\b\b\x1a\x1d\x1d\x1c\x0eËØÞYÝÚ[ÛÛKÜ\x1cØ\x19[\Ë\x1d^[[\x03BTN\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\x1a\x1d\x1d\x1c\x0eËØÞYÝÚ[ÛÛKÙ\KÃB^[ØÝ[Y[\x18]\x1a[Û\b\b\b\b\b\b\b\b\x1a\x1d\x1d\x1c\x0eËØÞYÝÚ[ÛÛKÙ^[ØÜË\x1d^[[\x03B[ÝXØÜXH\x1a[Î\b\b\b\b\b\x1a\x1d\x1d\x1c\x0eËØÞYÝÚ[ÛÛKÛ[\vÈÝ[ÝXØÜXK\Ú[\^[\x19CBB ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2018-04-09 15:55 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-04-07 17:40 Floating point exception in strtod() Ken Brown 2018-04-07 20:52 ` Dan Kegel 2018-04-08 12:57 ` Soegtrop, Michael 2018-04-07 20:56 ` Eliot Moss 2018-04-08 3:12 ` Duncan Roe 2018-04-08 10:25 ` Hans-Bernhard Bröker 2018-04-09 9:47 ` Corinna Vinschen 2018-04-09 12:09 ` Ken Brown 2018-04-09 12:51 ` Corinna Vinschen 2018-04-09 14:46 ` Soegtrop, Michael 2018-04-09 15:33 ` Corinna Vinschen 2018-04-09 15:55 ` Soegtrop, Michael
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).