diff options
author | Rich Felker <dalias@aerifal.cx> | 2012-04-21 13:50:23 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2012-04-21 13:50:23 -0400 |
commit | 2df2a97a20df22f598810b88409eb6107d23e7e1 (patch) | |
tree | 65ec9df277ea879b0aef02cba8117a7e0bc875d1 | |
parent | 33e7781b5b71eac594b6fa539f6d75939e9b676d (diff) | |
download | musl-2df2a97a20df22f598810b88409eb6107d23e7e1.tar.gz |
skip leading zeros even after decimal point in floatscan
in principle this should just be an optimization, but it happens to
also fix a nasty bug where values like 0.00000000001 were getting
caught by the early zero detection path and wrongly scanned as zero.
-rw-r--r-- | src/internal/floatscan.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/src/internal/floatscan.c b/src/internal/floatscan.c index b260381e..dbe07987 100644 --- a/src/internal/floatscan.c +++ b/src/internal/floatscan.c @@ -57,10 +57,10 @@ static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int po uint32_t x[KMAX]; static const uint32_t th[] = { LD_B1B_MAX }; int i, j, k, a, z; - long long lrp=-1, dc=0; + long long lrp=0, dc=0; long long e10=0; int lnz = 0; - int gotdig = 0; + int gotdig = 0, gotrad = 0; int rp; int e2; long double y; @@ -74,11 +74,16 @@ static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int po /* Don't let leading zeros consume buffer space */ for (; c=='0'; c = shgetc(f)) gotdig=1; + if (c=='.') { + gotrad = 1; + for (c = shgetc(f); c=='0'; c = shgetc(f)) gotdig=1, lrp--; + } x[0] = 0; for (; c-'0'<10U || c=='.'; c = shgetc(f)) { if (c == '.') { - if (lrp!=-1) break; + if (gotrad) break; + gotrad = 1; lrp = dc; } else if (k < KMAX-2) { dc++; @@ -95,7 +100,7 @@ static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int po if (c!='0') x[KMAX-3] |= 1; } } - if (lrp==-1) lrp=dc; + if (!gotrad) lrp=dc; if (gotdig && (c|32)=='e') { e10 = scanexp(f, pok); |