summaryrefslogtreecommitdiffstats
path: root/contrib/gdtoa
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2004-01-19 05:14:12 +0000
committerdas <das@FreeBSD.org>2004-01-19 05:14:12 +0000
commit2b54587e529691da13ad420858ce167f84023ce5 (patch)
treef5a48ebe72bfd4596e9dc99161743ce8c7dfc2cc /contrib/gdtoa
parentac4cce98d01fbe19f88ac1e217e7895ec38fdbac (diff)
downloadFreeBSD-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/gdtoa')
-rw-r--r--contrib/gdtoa/gethex.c18
-rw-r--r--contrib/gdtoa/strtod.c8
-rw-r--r--contrib/gdtoa/xsum0.out2
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
OpenPOWER on IntegriCloud