From 19927830ac81be23193cf865356face1794ef07e Mon Sep 17 00:00:00 2001 From: David Schultz Date: Mon, 19 Jan 2004 05:14:12 +0000 Subject: [PATCH] Import gdtoa 20040118. This revision addresses some corner cases in denormal and locale handling in strtod(). --- contrib/gdtoa/gethex.c | 18 ++++++++++-------- contrib/gdtoa/strtod.c | 8 +++++--- contrib/gdtoa/xsum0.out | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/contrib/gdtoa/gethex.c b/contrib/gdtoa/gethex.c index 0f9ae3348c6b..fadb5de81260 100644 --- a/contrib/gdtoa/gethex.c +++ b/contrib/gdtoa/gethex.c @@ -51,7 +51,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) ULong L, lostbits, *x; Long e, e1; #ifdef USE_LOCALE - char decimalpoint = *localeconv()->decimal_point; + unsigned char decimalpoint = *localeconv()->decimal_point; #else #define decimalpoint '.' #endif @@ -164,6 +164,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) if (e > fpi->emax) { ovfl: Bfree(b); + *bp = 0; return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; } irv = STRTOG_Normal; @@ -173,7 +174,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) if (n >= nbits) { switch (fpi->rounding) { case FPI_Round_near: - if (n == nbits && n < 2 || any_on(b,n-1)) + if (n == nbits && (n < 2 || any_on(b,n-1))) goto one_bit; break; case FPI_Round_up: @@ -191,6 +192,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) } } Bfree(b); + *bp = 0; return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow; } k = n - 1; @@ -224,18 +226,18 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) k = b->wds; b = increment(b); x = b->x; - if (b->wds > k + if (irv == STRTOG_Denormal) { + if (nbits == fpi->nbits - 1 + && x[nbits >> kshift] & 1 << (nbits & kmask)) + irv = STRTOG_Normal; + } + else if (b->wds > k || (n = nbits & kmask) !=0 && hi0bits(x[k-1]) < 32-n) { rshift(b,1); if (++e > fpi->emax) goto ovfl; } - else if (irv == STRTOG_Denormal) { - k = nbits - 1; - if (x[k >> kshift] & 1 << (k & kmask)) - irv = STRTOG_Normal; - } irv |= STRTOG_Inexhi; } else diff --git a/contrib/gdtoa/strtod.c b/contrib/gdtoa/strtod.c index f1a0c0495786..4913d5089c94 100644 --- a/contrib/gdtoa/strtod.c +++ b/contrib/gdtoa/strtod.c @@ -114,15 +114,17 @@ strtod switch(s[1]) { case 'x': case 'X': - switch(i = gethex(&s, &fpi, &exp, &bb, sign)) { + switch((i = gethex(&s, &fpi, &exp, &bb, sign)) & STRTOG_Retmask) { case STRTOG_NoNumber: s = s00; sign = 0; case STRTOG_Zero: break; default: - copybits(bits, fpi.nbits, bb); - Bfree(bb); + if (bb) { + copybits(bits, fpi.nbits, bb); + Bfree(bb); + } ULtod(((U*)&rv)->L, bits, exp, i); } goto ret; diff --git a/contrib/gdtoa/xsum0.out b/contrib/gdtoa/xsum0.out index e5ec8f782275..b61d0f0bb64d 100644 --- a/contrib/gdtoa/xsum0.out +++ b/contrib/gdtoa/xsum0.out @@ -12,7 +12,7 @@ g_xfmt.c c20a5e4 2795 gdtoa.c 364a0d2 17017 gdtoa.h 1eb440de 4810 gdtoaimp.h 6a955ba 19106 -gethex.c 1310d1b3 5066 +gethex.c 1c586a03 5075 gmisc.c e1a268ea 2114 hd_init.c cf9a94e 1827 hexnan.c f53be1da 2988