summaryrefslogtreecommitdiff
path: root/stdlib
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2006-12-10 10:38:56 +0000
committerJakub Jelinek <jakub@redhat.com>2006-12-10 10:38:56 +0000
commitb0ec19ce6e64c405fdd95c90a5d4212f86abea1f (patch)
tree9f52f1f004f36f9bd712fe2fb753736733f6324c /stdlib
parent7f65f3e3920a0dd6bb6a8774f46063371be4d029 (diff)
Updated to fedora-glibc-20061210T1006
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/Makefile3
-rw-r--r--stdlib/strtod_l.c36
-rw-r--r--stdlib/tst-atof1.c19
-rw-r--r--stdlib/tst-atof2.c55
4 files changed, 95 insertions, 18 deletions
diff --git a/stdlib/Makefile b/stdlib/Makefile
index a0ff427b7e..37400ec547 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -66,7 +66,8 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
test-canon test-canon2 tst-strtoll tst-environ \
tst-xpg-basename tst-random tst-random2 tst-bsearch \
tst-limits tst-rand48 bug-strtod tst-setcontext \
- test-a64l tst-qsort tst-system testmb2 bug-strtod2
+ test-a64l tst-qsort tst-system testmb2 bug-strtod2 \
+ tst-atof1 tst-atof2 tst-strtod2
include ../Makeconfig
diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
index e13f1086da..b926aeba56 100644
--- a/stdlib/strtod_l.c
+++ b/stdlib/strtod_l.c
@@ -662,20 +662,20 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
/* If no other digit but a '0' is found the result is 0.0.
Return current read pointer. */
- if ((c < L_('0') || c > L_('9'))
- && (base == 16 && (c < (CHAR_TYPE) TOLOWER (L_('a'))
- || c > (CHAR_TYPE) TOLOWER (L_('f'))))
+ if (!((c >= L_('0') && c <= L_('9'))
+ || (base == 16 && ((CHAR_TYPE) TOLOWER (c) >= L_('a')
+ && (CHAR_TYPE) TOLOWER (c) <= L_('f')))
#ifdef USE_WIDE_CHAR
- && c != (wint_t) decimal
+ || c == (wint_t) decimal
#else
- && ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt)
+ || ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt)
if (decimal[cnt] != cp[cnt])
break;
- decimal[cnt] != '\0'; })
+ decimal[cnt] == '\0'; })
#endif
- && (base == 16 && (cp == start_of_digits
- || (CHAR_TYPE) TOLOWER (c) != L_('p')))
- && (base != 16 && (CHAR_TYPE) TOLOWER (c) != L_('e')))
+ || (base == 16 && (cp != start_of_digits
+ && (CHAR_TYPE) TOLOWER (c) == L_('p')))
+ || (base != 16 && (CHAR_TYPE) TOLOWER (c) == L_('e'))))
{
#ifdef USE_WIDE_CHAR
tp = __correctly_grouped_prefixwc (start_of_digits, cp, thousands,
@@ -759,13 +759,15 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
}
}
- /* We have the number digits in the integer part. Whether these are all or
- any is really a fractional digit will be decided later. */
+ /* We have the number of digits in the integer part. Whether these
+ are all or any is really a fractional digit will be decided
+ later. */
int_no = dig_no;
lead_zero = int_no == 0 ? -1 : 0;
- /* Read the fractional digits. A special case are the 'american style'
- numbers like `16.' i.e. with decimal but without trailing digits. */
+ /* Read the fractional digits. A special case are the 'american
+ style' numbers like `16.' i.e. with decimal point but without
+ trailing digits. */
if (
#ifdef USE_WIDE_CHAR
c == (wint_t) decimal
@@ -815,15 +817,16 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
if (base == 16)
exp_limit = (exp_negative ?
-MIN_EXP + MANT_DIG + 4 * int_no :
- MAX_EXP - 4 * int_no + lead_zero);
+ MAX_EXP - 4 * int_no + 4 * lead_zero + 3);
else
exp_limit = (exp_negative ?
-MIN_10_EXP + MANT_DIG + int_no :
- MAX_10_EXP - int_no + lead_zero);
+ MAX_10_EXP - int_no + lead_zero + 1);
do
{
exponent *= 10;
+ exponent += c - L_('0');
if (exponent > exp_limit)
/* The exponent is too large/small to represent a valid
@@ -853,7 +856,6 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
/* NOTREACHED */
}
- exponent += c - L_('0');
c = *++cp;
}
while (c >= L_('0') && c <= L_('9'));
@@ -888,7 +890,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
--expp;
--dig_no;
--int_no;
- ++exponent;
+ exponent += base == 16 ? 4 : 1;
}
while (dig_no > 0 && exponent < 0);
diff --git a/stdlib/tst-atof1.c b/stdlib/tst-atof1.c
new file mode 100644
index 0000000000..879d866558
--- /dev/null
+++ b/stdlib/tst-atof1.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int
+do_test (void)
+{
+ char buf[100];
+ snprintf (buf, sizeof (buf), "%g", atof ("0x10p-1"));
+ if (strcmp (buf, "8") != 0)
+ {
+ printf ("got \"%s\", expected \"8\"\n", buf);
+ return 1;
+ }
+ return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdlib/tst-atof2.c b/stdlib/tst-atof2.c
new file mode 100644
index 0000000000..74dac87b0d
--- /dev/null
+++ b/stdlib/tst-atof2.c
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static const struct
+{
+ const char *str;
+ const char *expected;
+} tests[] =
+ {
+ { "1e308", "1e+308" },
+ { "100000000e300", "1e+308" },
+ { "0x1p1023", "8.98847e+307" },
+ { "0x1000p1011", "8.98847e+307" },
+ { "0x1p1020", "1.12356e+307" },
+ { "0x0.00001p1040", "1.12356e+307" },
+ { "1e-307", "1e-307" },
+ { "0.000001e-301", "1e-307" },
+ { "0.0000001e-300", "1e-307" },
+ { "0.00000001e-299", "1e-307" },
+ { "1000000e-313", "1e-307" },
+ { "10000000e-314", "1e-307" },
+ { "100000000e-315", "1e-307" },
+ { "0x1p-1021", "4.45015e-308" },
+ { "0x1000p-1033", "4.45015e-308" },
+ { "0x10000p-1037", "4.45015e-308" },
+ { "0x0.001p-1009", "4.45015e-308" },
+ { "0x0.0001p-1005", "4.45015e-308" },
+ };
+#define NTESTS (sizeof (tests) / sizeof (tests[0]))
+
+
+static int
+do_test (void)
+{
+ int status = 0;
+
+ for (int i = 0; i < NTESTS; ++i)
+ {
+ char buf[100];
+ snprintf (buf, sizeof (buf), "%g", atof (tests[i].str));
+ if (strcmp (buf, tests[i].expected) != 0)
+ {
+ printf ("%d: got \"%s\", expected \"%s\"\n",
+ i, buf, tests[i].expected);
+ status = 1;
+ }
+ }
+
+ return status;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"