summaryrefslogtreecommitdiff
path: root/strings/dtoa.c
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-03-09 08:06:59 +0100
committerSergei Golubchik <sergii@pisem.net>2012-03-09 08:06:59 +0100
commit4933d21e5d93840ddcf41bf25ed92fbe253ae92d (patch)
treea4d892b86aa46927978f82976fff61f1e5193383 /strings/dtoa.c
parent97ee59d27d3daca806fdb3577df5a0e0a45a0a30 (diff)
parent7009bf411a8cb9a6e035b761b5e6352b4f474303 (diff)
downloadmariadb-git-4933d21e5d93840ddcf41bf25ed92fbe253ae92d.tar.gz
merge with mysql-5.5.21
Diffstat (limited to 'strings/dtoa.c')
-rw-r--r--strings/dtoa.c49
1 files changed, 36 insertions, 13 deletions
diff --git a/strings/dtoa.c b/strings/dtoa.c
index a6912859c7f..2af561d0564 100644
--- a/strings/dtoa.c
+++ b/strings/dtoa.c
@@ -782,7 +782,20 @@ static Bigint *multadd(Bigint *b, int m, int a, Stack_alloc *alloc)
return b;
}
-
+/**
+ Converts a string to Bigint.
+
+ Now we have nd0 digits, starting at s, followed by a
+ decimal point, followed by nd-nd0 digits.
+ Unless nd0 == nd, in which case we have a number of the form:
+ ".xxxxxx" or "xxxxxx."
+
+ @param s Input string, already partially parsed by my_strtod_int().
+ @param nd0 Number of digits before decimal point.
+ @param nd Total number of digits.
+ @param y9 Pre-computed value of the first nine digits.
+ @param alloc Stack allocator for Bigints.
+ */
static Bigint *s2b(const char *s, int nd0, int nd, ULong y9, Stack_alloc *alloc)
{
Bigint *b;
@@ -802,10 +815,11 @@ static Bigint *s2b(const char *s, int nd0, int nd, ULong y9, Stack_alloc *alloc)
do
b= multadd(b, 10, *s++ - '0', alloc);
while (++i < nd0);
- s++;
+ s++; /* skip '.' */
}
else
s+= 10;
+ /* now do the fractional part */
for(; i < nd; i++)
b= multadd(b, 10, *s++ - '0', alloc);
return b;
@@ -1415,20 +1429,29 @@ static double my_strtod_int(const char *s00, char **se, int *error, char *buf, s
for (; s < end && (c= *s) >= '0' && c <= '9'; ++s)
{
have_dig:
- nz++;
- if (c-= '0')
+ /*
+ Here we are parsing the fractional part.
+ We can stop counting digits after a while: the extra digits
+ will not contribute to the actual result produced by s2b().
+ We have to continue scanning, in case there is an exponent part.
+ */
+ if (nd < 2 * DBL_DIG)
{
- nf+= nz;
- for (i= 1; i < nz; i++)
+ nz++;
+ if (c-= '0')
+ {
+ nf+= nz;
+ for (i= 1; i < nz; i++)
+ if (nd++ < 9)
+ y*= 10;
+ else if (nd <= DBL_DIG + 1)
+ z*= 10;
if (nd++ < 9)
- y*= 10;
+ y= 10*y + c;
else if (nd <= DBL_DIG + 1)
- z*= 10;
- if (nd++ < 9)
- y= 10*y + c;
- else if (nd <= DBL_DIG + 1)
- z= 10*z + c;
- nz= 0;
+ z= 10*z + c;
+ nz= 0;
+ }
}
}
}