diff options
author | das <das@FreeBSD.org> | 2004-01-19 05:14:12 +0000 |
---|---|---|
committer | das <das@FreeBSD.org> | 2004-01-19 05:14:12 +0000 |
commit | 2b54587e529691da13ad420858ce167f84023ce5 (patch) | |
tree | f5a48ebe72bfd4596e9dc99161743ce8c7dfc2cc /contrib | |
parent | ac4cce98d01fbe19f88ac1e217e7895ec38fdbac (diff) | |
download | FreeBSD-src-2b54587e529691da13ad420858ce167f84023ce5.zip FreeBSD-src-2b54587e529691da13ad420858ce167f84023ce5.tar.gz |
Import gdtoa 20040118. This revision addresses some corner cases in
denormal and locale handling in strtod().
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/gdtoa/gethex.c | 18 | ||||
-rw-r--r-- | contrib/gdtoa/strtod.c | 8 | ||||
-rw-r--r-- | 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 0f9ae33..fadb5de 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 f1a0c04..4913d50 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 e5ec8f7..b61d0f0 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 |