}
for (x=0; c-'0'<10U && x<INT_MAX/10; c = shgetc(f))
x = 10*x + c-'0';
- for (y=x; c-'0'<10U && x<LLONG_MAX/10; c = shgetc(f))
+ for (y=x; c-'0'<10U && x<LLONG_MAX/100; c = shgetc(f))
y = 10*y + c-'0';
for (; c-'0'<10U; c = shgetc(f));
shunget(f);
}
-static long double decfloat(FILE *f, int bits, int emin, int sign, int pok)
+static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int pok)
{
uint32_t x[KMAX];
static const uint32_t th[] = { LD_B1B_MAX };
long double y;
long double frac=0;
long double bias=0;
- int c;
j=0;
k=0;
- c = shgetc(f);
-
/* Don't let leading zeros consume buffer space */
for (; c=='0'; c = shgetc(f)) gotdig=1;
if (c == '.') {
if (lrp!=-1) break;
lrp = dc;
- } else if (k < KMAX) {
+ } else if (k < KMAX-2) {
dc++;
if (j) x[k] = x[k]*10 + c-'0';
else x[k] = c-'0';
gotdig=1;
} else {
dc++;
- x[KMAX-1] |= c-'0';
+ if (c!='0') x[KMAX-3] |= 1;
}
}
if (lrp==-1) lrp=dc;
e2 = 0;
rp = lrp;
- while (rp < 18+9*LD_B1B_DIG) {
+ if (rp % 9) {
+ static const int p10s[] = {
+ 100000000, 10000000, 1000000, 100000,
+ 10000, 1000, 100, 10
+ };
+ int rpm9 = rp>=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]<th[0])) {
uint32_t carry = 0;
e2 -= 29;
for (k=(z-1 & MASK); ; k=(k-1 & MASK)) {
}
}
- if (rp % 9) {
- static const int p10s[] = {
- 100000000, 10000000, 1000000, 100000,
- 10000, 1000, 100, 10
- };
- int rpm9 = rp % 9;
- int p10 = p10s[rpm9-1];
- uint32_t carry = 0;
- for (k=a; k!=z; k=(k+1 & MASK)) {
- 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) {
- if ((z+1 & MASK) != a) {
- x[z] = carry;
- z = (z+1 & MASK);
- } else x[z-1 & MASK] |= 1;
- }
- rp += 9-rpm9;
- }
-
for (;;) {
uint32_t carry = 0;
int sh = 1;
/* FIXME: find a way to compute optimal sh */
if (rp > 9+9*LD_B1B_DIG) sh = 9;
e2 += sh;
- for (k=a; k!=z; k=(k+1 & MASK)) {
+ for (i=0; (k=(a+i & MASK))!=z && i<LD_B1B_DIG+3; i++) {
uint32_t tmp = x[k] & (1<<sh)-1;
x[k] = (x[k]>>sh) + carry;
carry = (1000000000>>sh) * tmp;
if (k==a && !x[k]) {
a = (a+1 & MASK);
+ i--;
rp -= 9;
}
}
- if (carry) {
+ if (carry && k==z) {
if ((z+1 & MASK) != a) {
x[z] = carry;
z = (z+1 & MASK);
}
}
- for (y=i=0; i<LD_B1B_DIG && (a+i & MASK)!=z; i++)
+ for (y=i=0; i<LD_B1B_DIG; i++) {
+ if ((a+i & MASK)==z) x[z=(z+1 & MASK)] = 0;
y = 1000000000.0L * y + x[a+i & MASK];
+ }
y *= sign;
}
e2 = 0;
}
+ } else {
+ shunget(f);
}
e2 += 4*rp - 32;
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);
}