X-Git-Url: http://nsz.repo.hu/git/?p=musl;a=blobdiff_plain;f=src%2Finternal%2Ffloatscan.c;h=6390d46a1372089e41c82c0931a1eb7dd4058642;hp=7d9a452412592a06955e2f4cf7aeeb1cd004a4b6;hb=5837a0bb6b5cf516f79527e837368af0b494d51a;hpb=2162541f38d3f642f5a643010548d62220d55a4d diff --git a/src/internal/floatscan.c b/src/internal/floatscan.c index 7d9a4524..6390d46a 100644 --- a/src/internal/floatscan.c +++ b/src/internal/floatscan.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "shgetc.h" #include "floatscan.h" @@ -43,7 +44,7 @@ static long long scanexp(FILE *f, int pok) } for (x=0; c-'0'<10U && x30 || x[0]>>bits==0)) return sign * (long double)x[0]; - if (lrp > -emin/2) + if (lrp > -emin/2) { + errno = ERANGE; return sign * LDBL_MAX * LDBL_MAX; - if (lrp < emin-2*LDBL_MANT_DIG) + } + if (lrp < emin-2*LDBL_MANT_DIG) { + errno = ERANGE; return sign * LDBL_MIN * LDBL_MIN; + } if (k=0 ? rp%9 : rp%9+9; + int p10 = p10s[rpm9-1]; + uint32_t carry = 0; + for (k=a; k!=z; k++) { + uint32_t tmp = x[k] % p10; + x[k] = x[k]/p10 + carry; + carry = 1000000000/p10 * tmp; + if (k==a && !x[k]) { + a = (a+1 & MASK); + rp -= 9; + } + } + if (carry) x[z++] = carry; + rp += 9-rpm9; + } + + while (rp < 9*LD_B1B_DIG || (rp == 9*LD_B1B_DIG && x[0] -emin) return sign * LDBL_MAX * LDBL_MAX; - if (e2 < emin-2*LDBL_MANT_DIG) return sign * LDBL_MIN * LDBL_MIN; + if (e2 > -emin) { + errno = ERANGE; + return sign * LDBL_MAX * LDBL_MAX; + } + if (e2 < emin-2*LDBL_MANT_DIG) { + errno = ERANGE; + return sign * LDBL_MIN * LDBL_MIN; + } while (x < 0x80000000) { if (y>=0.5) { @@ -359,6 +369,8 @@ static long double hexfloat(FILE *f, int bits, int emin, int sign, int pok) y = bias + sign*(long double)x + sign*y; y -= bias; + if (!y) errno = ERANGE; + return scalbnl(y, e2); } @@ -409,6 +421,7 @@ long double __floatscan(FILE *f, int c, int prec, int pok) if (i) { shunget(f); + errno = EINVAL; shlim(f, 0); return 0; } @@ -417,9 +430,9 @@ long double __floatscan(FILE *f, int c, int prec, int pok) c = shgetc(f); if ((c|32) == 'x') return hexfloat(f, bits, emin, sign, pok); + shunget(f); c = '0'; } - shunget(f); - return decfloat(f, bits, emin, sign, pok); + return decfloat(f, c, bits, emin, sign, pok); }