summaryrefslogtreecommitdiff
path: root/src/internal/floatscan.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-04-21 13:50:23 -0400
committerRich Felker <dalias@aerifal.cx>2012-04-21 13:50:23 -0400
commit2df2a97a20df22f598810b88409eb6107d23e7e1 (patch)
tree65ec9df277ea879b0aef02cba8117a7e0bc875d1 /src/internal/floatscan.c
parent33e7781b5b71eac594b6fa539f6d75939e9b676d (diff)
downloadmusl-2df2a97a20df22f598810b88409eb6107d23e7e1.tar.gz
musl-2df2a97a20df22f598810b88409eb6107d23e7e1.tar.bz2
musl-2df2a97a20df22f598810b88409eb6107d23e7e1.tar.xz
musl-2df2a97a20df22f598810b88409eb6107d23e7e1.zip
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.
Diffstat (limited to 'src/internal/floatscan.c')
-rw-r--r--src/internal/floatscan.c13
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);