]>
Commit | Line | Data |
---|---|---|
7c3018f9 | 1 | /* Basic tests for strtod. |
2b778ceb | 2 | Copyright (C) 1991-2021 Free Software Foundation, Inc. |
afd4eb37 | 3 | This file is part of the GNU C Library. |
28f540f4 | 4 | |
afd4eb37 | 5 | The GNU C Library is free software; you can redistribute it and/or |
41bdb6e2 AJ |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
28f540f4 | 9 | |
afd4eb37 UD |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
28f540f4 | 14 | |
41bdb6e2 | 15 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 | 16 | License along with the GNU C Library; if not, see |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
28f540f4 | 18 | |
28f540f4 | 19 | #include <ctype.h> |
dc5fd907 UD |
20 | #include <locale.h> |
21 | #include <stddef.h> | |
28f540f4 RM |
22 | #include <stdio.h> |
23 | #include <stdlib.h> | |
24 | #include <errno.h> | |
25 | #include <string.h> | |
a529b416 | 26 | #include <math.h> |
28f540f4 RM |
27 | |
28 | struct ltest | |
29 | { | |
afd4eb37 | 30 | const char *str; /* Convert this. */ |
28f540f4 RM |
31 | double expect; /* To get this. */ |
32 | char left; /* With this left over. */ | |
33 | int err; /* And this in errno. */ | |
34 | }; | |
afd4eb37 | 35 | static const struct ltest tests[] = |
28f540f4 RM |
36 | { |
37 | { "12.345", 12.345, '\0', 0 }, | |
38 | { "12.345e19", 12.345e19, '\0', 0 }, | |
39 | { "-.1e+9", -.1e+9, '\0', 0 }, | |
40 | { ".125", .125, '\0', 0 }, | |
41 | { "1e20", 1e20, '\0', 0 }, | |
afd4eb37 | 42 | { "0e-19", 0, '\0', 0 }, |
6259ec0d | 43 | { "4\00012", 4.0, '\0', 0 }, |
fb5663ca | 44 | { "5.9e-76", 5.9e-76, '\0', 0 }, |
cd33623e | 45 | { "0x1.4p+3", 10.0, '\0', 0 }, |
2aa562e8 UD |
46 | { "0xAp0", 10.0, '\0', 0 }, |
47 | { "0x0Ap0", 10.0, '\0', 0 }, | |
cd33623e | 48 | { "0x0A", 10.0, '\0', 0 }, |
6491b809 UD |
49 | { "0xA0", 160.0, '\0', 0 }, |
50 | { "0x0.A0p8", 160.0, '\0', 0 }, | |
51 | { "0x0.50p9", 160.0, '\0', 0 }, | |
52 | { "0x0.28p10", 160.0, '\0', 0 }, | |
53 | { "0x0.14p11", 160.0, '\0', 0 }, | |
54 | { "0x0.0A0p12", 160.0, '\0', 0 }, | |
55 | { "0x0.050p13", 160.0, '\0', 0 }, | |
56 | { "0x0.028p14", 160.0, '\0', 0 }, | |
57 | { "0x0.014p15", 160.0, '\0', 0 }, | |
58 | { "0x00.00A0p16", 160.0, '\0', 0 }, | |
59 | { "0x00.0050p17", 160.0, '\0', 0 }, | |
60 | { "0x00.0028p18", 160.0, '\0', 0 }, | |
61 | { "0x00.0014p19", 160.0, '\0', 0 }, | |
eab1830e AJ |
62 | { "0x1p-1023", |
63 | 1.11253692925360069154511635866620203210960799023116591527666e-308, | |
2a27fd6d | 64 | '\0', 0 }, |
eab1830e AJ |
65 | { "0x0.8p-1022", |
66 | 1.11253692925360069154511635866620203210960799023116591527666e-308, | |
2a27fd6d | 67 | '\0', 0 }, |
a529b416 UD |
68 | { "Inf", HUGE_VAL, '\0', 0 }, |
69 | { "-Inf", -HUGE_VAL, '\0', 0 }, | |
70 | { "+InFiNiTy", HUGE_VAL, '\0', 0 }, | |
85b5767c | 71 | { "0x80000Ap-23", 0x80000Ap-23, '\0', 0 }, |
04d08991 | 72 | { "1e-324", 0, '\0', ERANGE }, |
8f203e6c JM |
73 | { "0x100000000000008p0", 0x1p56, '\0', 0 }, |
74 | { "0x100000000000008.p0", 0x1p56, '\0', 0 }, | |
75 | { "0x100000000000008.00p0", 0x1p56, '\0', 0 }, | |
76 | { "0x10000000000000800p0", 0x1p64, '\0', 0 }, | |
77 | { "0x10000000000000801p0", 0x1.0000000000001p64, '\0', 0 }, | |
28f540f4 RM |
78 | { NULL, 0, '\0', 0 } |
79 | }; | |
80 | ||
46827b5c UD |
81 | static void expand (char *dst, int c); |
82 | static int long_dbl (void); | |
28f540f4 | 83 | |
c1f41083 AS |
84 | static int |
85 | do_test (void) | |
28f540f4 | 86 | { |
936365c1 | 87 | char buf[100]; |
2e09a79a | 88 | const struct ltest *lt; |
28f540f4 RM |
89 | char *ep; |
90 | int status = 0; | |
5ae9d168 | 91 | int save_errno; |
28f540f4 RM |
92 | |
93 | for (lt = tests; lt->str != NULL; ++lt) | |
94 | { | |
95 | double d; | |
96 | ||
97 | errno = 0; | |
98 | d = strtod(lt->str, &ep); | |
5ae9d168 UD |
99 | save_errno = errno; |
100 | printf ("strtod (\"%s\") test %u", | |
28f540f4 | 101 | lt->str, (unsigned int) (lt - tests)); |
5ae9d168 UD |
102 | if (d == lt->expect && *ep == lt->left && save_errno == lt->err) |
103 | puts ("\tOK"); | |
28f540f4 RM |
104 | else |
105 | { | |
5ae9d168 | 106 | puts ("\tBAD"); |
28f540f4 | 107 | if (d != lt->expect) |
5ae9d168 | 108 | printf (" returns %.60g, expected %.60g\n", d, lt->expect); |
28f540f4 RM |
109 | if (lt->left != *ep) |
110 | { | |
111 | char exp1[5], exp2[5]; | |
5ae9d168 UD |
112 | expand (exp1, *ep); |
113 | expand (exp2, lt->left); | |
114 | printf (" leaves '%s', expected '%s'\n", exp1, exp2); | |
28f540f4 | 115 | } |
5ae9d168 UD |
116 | if (save_errno != lt->err) |
117 | printf (" errno %d (%s) instead of %d (%s)\n", | |
118 | save_errno, strerror (save_errno), | |
119 | lt->err, strerror (lt->err)); | |
28f540f4 RM |
120 | status = 1; |
121 | } | |
122 | } | |
123 | ||
936365c1 UD |
124 | sprintf (buf, "%f", strtod ("-0.0", NULL)); |
125 | if (strcmp (buf, "-0.000000") != 0) | |
126 | { | |
431c33c0 | 127 | printf (" strtod (\"-0.0\", NULL) returns \"%s\"\n", buf); |
936365c1 UD |
128 | status = 1; |
129 | } | |
130 | ||
b5f7b119 UD |
131 | const char input[] = "3752432815e-39"; |
132 | ||
133 | float f1 = strtold (input, NULL); | |
134 | float f2; | |
135 | float f3 = strtof (input, NULL); | |
136 | sscanf (input, "%g", &f2); | |
137 | ||
138 | if (f1 != f2) | |
139 | { | |
140 | printf ("f1 = %a != f2 = %a\n", f1, f2); | |
141 | status = 1; | |
142 | } | |
143 | if (f1 != f3) | |
144 | { | |
145 | printf ("f1 = %a != f3 = %a\n", f1, f3); | |
146 | status = 1; | |
147 | } | |
148 | if (f2 != f3) | |
149 | { | |
150 | printf ("f2 = %a != f3 = %a\n", f2, f3); | |
151 | status = 1; | |
152 | } | |
153 | ||
286a45c5 | 154 | const char input2[] = "+1.000000000116415321826934814453125"; |
c53320c0 | 155 | if (strtold (input2, NULL) != +1.000000000116415321826934814453125L) |
286a45c5 UD |
156 | { |
157 | printf ("input2: %La != %La\n", strtold (input2, NULL), | |
fa4a36fd | 158 | +1.000000000116415321826934814453125L); |
286a45c5 UD |
159 | status = 1; |
160 | } | |
161 | ||
deddf809 UD |
162 | static struct { const char *str; long double l; } ltests[] = |
163 | { | |
164 | { "42.0000000000000000001", 42.0000000000000000001L }, | |
165 | { "42.00000000000000000001", 42.00000000000000000001L }, | |
166 | { "42.000000000000000000001", 42.000000000000000000001L } | |
167 | }; | |
168 | int n; | |
169 | for (n = 0; n < sizeof (ltests) / sizeof (ltests[0]); ++n) | |
170 | if (strtold (ltests[n].str, NULL) != ltests[n].l) | |
171 | { | |
172 | printf ("ltests[%d]: %La != %La\n", n, | |
173 | strtold (ltests[n].str, NULL), ltests[n].l); | |
174 | status = 1; | |
175 | } | |
176 | ||
46827b5c UD |
177 | status |= long_dbl (); |
178 | ||
bf4de8f3 | 179 | return status ? EXIT_FAILURE : EXIT_SUCCESS; |
28f540f4 RM |
180 | } |
181 | ||
182 | static void | |
9d46370c | 183 | expand (char *dst, int c) |
28f540f4 | 184 | { |
5ae9d168 | 185 | if (isprint (c)) |
28f540f4 RM |
186 | { |
187 | dst[0] = c; | |
188 | dst[1] = '\0'; | |
189 | } | |
190 | else | |
5ae9d168 | 191 | (void) sprintf (dst, "%#.3o", (unsigned int) c); |
28f540f4 | 192 | } |
46827b5c UD |
193 | |
194 | static int | |
195 | long_dbl (void) | |
196 | { | |
2827300f UD |
197 | /* Regenerate this string using |
198 | ||
199 | echo '(2^53-1)*2^(1024-53)' | bc | sed 's/\([^\]*\)\\*$/ "\1"/' | |
200 | ||
201 | */ | |
202 | static const char longestdbl[] = | |
203 | "17976931348623157081452742373170435679807056752584499659891747680315" | |
204 | "72607800285387605895586327668781715404589535143824642343213268894641" | |
205 | "82768467546703537516986049910576551282076245490090389328944075868508" | |
206 | "45513394230458323690322294816580855933212334827479782620414472316873" | |
207 | "8177180919299881250404026184124858368"; | |
46827b5c UD |
208 | double d = strtod (longestdbl, NULL); |
209 | ||
210 | printf ("strtod (\"%s\", NULL) = %g\n", longestdbl, d); | |
211 | ||
212 | if (d != 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000) | |
213 | return 1; | |
214 | ||
215 | return 0; | |
216 | } | |
dc5fd907 | 217 | |
7c3018f9 | 218 | #include <support/test-driver.c> |