From 5bc737f35262327ca86ef96a7cbc6680c8eeb2ea Mon Sep 17 00:00:00 2001 From: das Date: Wed, 3 Jan 2007 04:58:54 +0000 Subject: Import of the latest gdtoa sources, which include fixes for minor problems relating to NaNs and rounding. --- contrib/gdtoa/strtod.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'contrib/gdtoa/strtod.c') diff --git a/contrib/gdtoa/strtod.c b/contrib/gdtoa/strtod.c index 4913d50..66a3baa 100644 --- a/contrib/gdtoa/strtod.c +++ b/contrib/gdtoa/strtod.c @@ -26,12 +26,13 @@ THIS SOFTWARE. ****************************************************************/ -/* Please send bug reports to - David M. Gay - dmg@acm.org - */ +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ #include "gdtoaimp.h" +#ifndef NO_FENV_H +#include +#endif #ifdef USE_LOCALE #include "locale.h" @@ -68,7 +69,7 @@ strtod #ifdef Avoid_Underflow int scale; #endif - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; CONST char *s, *s0, *s1; double aadj, aadj1, adj, rv, rv0; @@ -82,7 +83,7 @@ strtod int rounding; #endif - sign = nz0 = nz = 0; + sign = nz0 = nz = decpt = 0; dval(rv) = 0.; for(s = s00;;s++) switch(*s) { case '-': @@ -114,7 +115,18 @@ strtod switch(s[1]) { case 'x': case 'X': - switch((i = gethex(&s, &fpi, &exp, &bb, sign)) & STRTOG_Retmask) { + { +#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) + FPI fpi1 = fpi; + switch(fegetround()) { + case FE_TOWARDZERO: fpi1.rounding = 0; break; + case FE_UPWARD: fpi1.rounding = 2; break; + case FE_DOWNWARD: fpi1.rounding = 3; + } +#else +#define fpi1 fpi +#endif + switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { case STRTOG_NoNumber: s = s00; sign = 0; @@ -126,7 +138,7 @@ strtod Bfree(bb); } ULtod(((U*)&rv)->L, bits, exp, i); - } + }} goto ret; } } @@ -150,6 +162,7 @@ strtod if (c == '.') #endif { + decpt = 1; c = *++s; if (!nd) { for(; c == '0'; c = *++s) @@ -225,7 +238,8 @@ strtod ULong bits[2]; static FPI fpinan = /* only 52 explicit bits */ { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; - switch(c) { + if (!decpt) + switch(c) { case 'i': case 'I': if (match(&s,"nf")) { @@ -248,8 +262,10 @@ strtod word1(rv) = bits[0]; } else { +#endif word0(rv) = NAN_WORD0; word1(rv) = NAN_WORD1; +#ifndef No_Hex_NaN } #endif goto ret; -- cgit v1.1