9 #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
12 #define LD_B1B_MAX 9007199, 254740991
15 #else /* LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 */
18 #define LD_B1B_MAX 18, 446744073, 709551615
27 #include "stdio_impl.h"
29 #define ungetc(c,f) ((f)->rpos--,(c))
31 #define getc getc_unlocked
35 static long long scanexp(FILE *f, off_t *pcnt)
42 *pcnt += (c=getc(f))>=0;
43 if (c=='+' || c=='-') {
45 *pcnt += (c=getc(f))>=0;
54 for (x=0; c-'0'<10U && x<INT_MAX/10; *pcnt += (c=getc(f))>=0)
56 for (y=x; c-'0'<10U && x<LLONG_MAX/10; *pcnt += (c=getc(f))>=0)
58 for (; c-'0'<10U; *pcnt += (c=getc(f))>=0);
67 static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int pok, off_t *pcnt)
70 static const uint32_t th[] = { LD_B1B_MAX };
72 long long lrp=-1, dc=0;
84 if (c<0) *pcnt += (c=getc(f))>=0;
86 /* Don't let leading zeros consume buffer space */
87 for (; c=='0'; *pcnt += (c=getc(f))>=0) gotdig=1;
90 for (; c-'0'<10U || c=='.'; *pcnt += (c=getc(f))>=0) {
94 } else if (k < KMAX) {
96 if (j) x[k] = x[k]*10 + c-'0';
110 if (gotdig && (c|32)=='e') {
111 e10 = scanexp(f, pcnt);
112 if (e10 == LLONG_MIN) {
131 if (lrp==dc && (!k || (k==1 && !j)) && (bits>30 || x[0]>>bits==0))
132 return sign * (long double)x[0];
134 return sign * LDBL_MAX * LDBL_MAX;
135 if (lrp < emin-2*LDBL_MANT_DIG)
136 return sign * LDBL_MIN * LDBL_MIN;
139 for (; j<9; j++) x[k]*=10;
149 while (rp < 18+9*LD_B1B_DIG) {
152 for (k=(z-1 & MASK); ; k=(k-1 & MASK)) {
153 uint64_t tmp = ((uint64_t)x[k] << 29) + carry;
154 if (tmp > 1000000000) {
155 carry = tmp / 1000000000;
156 x[k] = tmp % 1000000000;
161 if (k==(z-1 & MASK) && k!=a && !x[k]) z = k;
168 x[z-1 & MASK] |= x[z];
176 static const int p10s[] = {
177 100000000, 10000000, 1000000, 100000,
181 int p10 = p10s[rpm9-1];
183 for (k=a; k!=z; k=(k+1 & MASK)) {
184 uint32_t tmp = x[k] % p10;
185 x[k] = x[k]/p10 + carry;
186 carry = 1000000000/p10 * tmp;
193 if ((z+1 & MASK) != a) {
196 } else x[z-1 & MASK] |= 1;
204 for (i=0; i<LD_B1B_DIG; i++) {
206 if (k == z || x[k] < th[i]) {
210 if (x[a+i & MASK] > th[i]) break;
212 if (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break;
213 /* FIXME: find a way to compute optimal sh */
214 if (rp > 9+9*LD_B1B_DIG) sh = 9;
216 for (k=a; k!=z; k=(k+1 & MASK)) {
217 uint32_t tmp = x[k] & (1<<sh)-1;
218 x[k] = (x[k]>>sh) + carry;
219 carry = (1000000000>>sh) * tmp;
226 if ((z+1 & MASK) != a) {
229 } else x[z-1 & MASK] |= 1;
233 for (y=i=0; i<LD_B1B_DIG && (a+i & MASK)!=z; i++)
234 y = 1000000000.0L * y + x[a+i & MASK];
238 if (bits > LDBL_MANT_DIG+e2-emin) {
239 bits = LDBL_MANT_DIG+e2-emin;
243 if (bits < LDBL_MANT_DIG) {
244 bias = copysignl(scalbn(1, 2*LDBL_MANT_DIG-bits-1), y);
245 frac = fmodl(y, scalbn(1, LDBL_MANT_DIG-bits));
250 if ((a+i & MASK) != z) {
251 uint32_t t = x[a+i & MASK];
252 if (t < 500000000 && (t || (a+i+1 & MASK) != z))
254 else if (t > 500000000)
256 else if (t == 500000000) {
257 if ((a+i+1 & MASK) == z)
262 if (LDBL_MANT_DIG-bits >= 2 && !fmodl(frac, 1))
274 static long double hexfloat(FILE *f, int c, int bits, int emin, int sign, int pok, off_t *pcnt)
278 long double scale = 1;
279 long double bias = 0;
280 int gottail = 0, gotrad = 0, gotdig = 0;
286 if (c<0) *pcnt += (c=getc(f))>=0;
288 /* Skip leading zeros */
289 for (; c=='0'; *pcnt += (c=getc(f))>=0) gotdig = 1;
293 *pcnt += (c=getc(f))>=0;
294 /* Count zeros after the radix point before significand */
295 for (rp=0; c=='0'; *pcnt += (c=getc(f))>=0, rp--) gotdig = 1;
298 for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; *pcnt += (c=getc(f))>=0) {
305 if (c > '9') d = (c|32)+10-'a';
309 } else if (dc < LDBL_MANT_DIG/4+1) {
311 } else if (d && !gottail) {
323 if (pok) *pcnt -= 1+gotrad; /* uncount the rp, x of 0x */
327 if (!gotrad) rp = dc;
328 while (dc<8) x *= 16, dc++;
330 e2 = scanexp(f, pcnt);
331 if (e2 == LLONG_MIN) {
341 if (!x) return sign * 0.0;
342 if (e2 > -emin) return sign * LDBL_MAX * LDBL_MAX;
343 if (e2 < emin-2*LDBL_MANT_DIG) return sign * LDBL_MIN * LDBL_MIN;
345 while (x < 0x80000000) {
356 if (bits > 32+e2-emin) {
361 if (bits < LDBL_MANT_DIG)
362 bias = copysignl(scalbn(1, 32+LDBL_MANT_DIG-bits-1), sign);
364 if (bits<32 && y && !(x&1)) x++, y=0;
366 y = bias + sign*(long double)x + sign*y;
369 return scalbnl(y, e2);
372 long double __floatscan(FILE *f, int c, int prec, int pok, off_t *pcnt)
391 bits = LDBL_MANT_DIG;
398 if (c<0) *pcnt += (c=getc(f))>=0;
400 if (c=='+' || c=='-') {
402 *pcnt += (c=getc(f))>=0;
405 for (i=0; i<8 && (c|32)=="infinity"[i]; i++)
406 if (i<7) c = getc(f);
407 if (i==3 || i==8 || (i>3 && pok)) {
408 if (i==3 && c>=0) ungetc(c, f);
409 if (i==8) *pcnt += 7;
411 return sign * INFINITY;
413 if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++)
414 if (i<3) c = getc(f);
417 return sign>0 ? NAN : -NAN;
421 if (c>=0) ungetc(c, f);
427 *pcnt += (c=getc(f))>=0;
429 return hexfloat(f, -1, bits, emin, sign, pok, pcnt);
437 return decfloat(f, c, bits, emin, sign, pok, pcnt);