glob: Declare variables at the very start of their scope.
[gnulib/ericb.git] / tests / test-strtod.c
blobddfdedeb6057f35ec34bc2d54b4073aa33e09f3b
1 /*
2 * Copyright (C) 2008-2017 Free Software Foundation, Inc.
3 * Written by Eric Blake
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program 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
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 #include <config.h>
20 #include <stdlib.h>
22 #include "signature.h"
23 SIGNATURE_CHECK (strtod, double, (char const *, char **));
25 #include <errno.h>
26 #include <float.h>
27 #include <math.h>
28 #include <string.h>
30 #include "isnand-nolibm.h"
31 #include "minus-zero.h"
32 #include "macros.h"
34 /* Avoid requiring -lm just for fabs. */
35 #define FABS(d) ((d) < 0.0 ? -(d) : (d))
37 int
38 main (void)
40 int status = 0;
41 /* Subject sequence empty or invalid. */
43 const char input[] = "";
44 char *ptr;
45 double result;
46 errno = 0;
47 result = strtod (input, &ptr);
48 ASSERT (result == 0.0);
49 ASSERT (!signbit (result));
50 ASSERT (ptr == input);
51 ASSERT (errno == 0 || errno == EINVAL);
54 const char input[] = " ";
55 char *ptr;
56 double result;
57 errno = 0;
58 result = strtod (input, &ptr);
59 ASSERT (result == 0.0);
60 ASSERT (!signbit (result));
61 ASSERT (ptr == input);
62 ASSERT (errno == 0 || errno == EINVAL);
65 const char input[] = " +";
66 char *ptr;
67 double result;
68 errno = 0;
69 result = strtod (input, &ptr);
70 ASSERT (result == 0.0);
71 ASSERT (!signbit (result));
72 ASSERT (ptr == input);
73 ASSERT (errno == 0 || errno == EINVAL);
76 const char input[] = " .";
77 char *ptr;
78 double result;
79 errno = 0;
80 result = strtod (input, &ptr);
81 ASSERT (result == 0.0);
82 ASSERT (!signbit (result));
83 ASSERT (ptr == input);
84 ASSERT (errno == 0 || errno == EINVAL);
87 const char input[] = " .e0";
88 char *ptr;
89 double result;
90 errno = 0;
91 result = strtod (input, &ptr);
92 ASSERT (result == 0.0);
93 ASSERT (!signbit (result));
94 ASSERT (ptr == input); /* IRIX 6.5, OSF/1 5.1 */
95 ASSERT (errno == 0 || errno == EINVAL);
98 const char input[] = " +.e-0";
99 char *ptr;
100 double result;
101 errno = 0;
102 result = strtod (input, &ptr);
103 ASSERT (result == 0.0);
104 ASSERT (!signbit (result));
105 ASSERT (ptr == input); /* IRIX 6.5, OSF/1 5.1 */
106 ASSERT (errno == 0 || errno == EINVAL);
109 const char input[] = " in";
110 char *ptr;
111 double result;
112 errno = 0;
113 result = strtod (input, &ptr);
114 ASSERT (result == 0.0);
115 ASSERT (!signbit (result));
116 ASSERT (ptr == input);
117 ASSERT (errno == 0 || errno == EINVAL);
120 const char input[] = " na";
121 char *ptr;
122 double result;
123 errno = 0;
124 result = strtod (input, &ptr);
125 ASSERT (result == 0.0);
126 ASSERT (!signbit (result));
127 ASSERT (ptr == input);
128 ASSERT (errno == 0 || errno == EINVAL);
131 /* Simple floating point values. */
133 const char input[] = "1";
134 char *ptr;
135 double result;
136 errno = 0;
137 result = strtod (input, &ptr);
138 ASSERT (result == 1.0);
139 ASSERT (ptr == input + 1);
140 ASSERT (errno == 0);
143 const char input[] = "1.";
144 char *ptr;
145 double result;
146 errno = 0;
147 result = strtod (input, &ptr);
148 ASSERT (result == 1.0);
149 ASSERT (ptr == input + 2);
150 ASSERT (errno == 0);
153 const char input[] = ".5";
154 char *ptr;
155 double result;
156 errno = 0;
157 result = strtod (input, &ptr);
158 /* FIXME - gnulib's version is rather inaccurate. It would be
159 nice to guarantee an exact result, but for now, we settle for a
160 1-ulp error. */
161 ASSERT (FABS (result - 0.5) < DBL_EPSILON);
162 ASSERT (ptr == input + 2);
163 ASSERT (errno == 0);
166 const char input[] = " 1";
167 char *ptr;
168 double result;
169 errno = 0;
170 result = strtod (input, &ptr);
171 ASSERT (result == 1.0);
172 ASSERT (ptr == input + 2);
173 ASSERT (errno == 0);
176 const char input[] = "+1";
177 char *ptr;
178 double result;
179 errno = 0;
180 result = strtod (input, &ptr);
181 ASSERT (result == 1.0);
182 ASSERT (ptr == input + 2);
183 ASSERT (errno == 0);
186 const char input[] = "-1";
187 char *ptr;
188 double result;
189 errno = 0;
190 result = strtod (input, &ptr);
191 ASSERT (result == -1.0);
192 ASSERT (ptr == input + 2);
193 ASSERT (errno == 0);
196 const char input[] = "1e0";
197 char *ptr;
198 double result;
199 errno = 0;
200 result = strtod (input, &ptr);
201 ASSERT (result == 1.0);
202 ASSERT (ptr == input + 3);
203 ASSERT (errno == 0);
206 const char input[] = "1e+0";
207 char *ptr;
208 double result;
209 errno = 0;
210 result = strtod (input, &ptr);
211 ASSERT (result == 1.0);
212 ASSERT (ptr == input + 4);
213 ASSERT (errno == 0);
216 const char input[] = "1e-0";
217 char *ptr;
218 double result;
219 errno = 0;
220 result = strtod (input, &ptr);
221 ASSERT (result == 1.0);
222 ASSERT (ptr == input + 4);
223 ASSERT (errno == 0);
226 const char input[] = "1e1";
227 char *ptr;
228 double result;
229 errno = 0;
230 result = strtod (input, &ptr);
231 ASSERT (result == 10.0);
232 ASSERT (ptr == input + 3);
233 ASSERT (errno == 0);
236 const char input[] = "5e-1";
237 char *ptr;
238 double result;
239 errno = 0;
240 result = strtod (input, &ptr);
241 /* FIXME - gnulib's version is rather inaccurate. It would be
242 nice to guarantee an exact result, but for now, we settle for a
243 1-ulp error. */
244 ASSERT (FABS (result - 0.5) < DBL_EPSILON);
245 ASSERT (ptr == input + 4);
246 ASSERT (errno == 0);
249 /* Zero. */
251 const char input[] = "0";
252 char *ptr;
253 double result;
254 errno = 0;
255 result = strtod (input, &ptr);
256 ASSERT (result == 0.0);
257 ASSERT (!signbit (result));
258 ASSERT (ptr == input + 1);
259 ASSERT (errno == 0);
262 const char input[] = ".0";
263 char *ptr;
264 double result;
265 errno = 0;
266 result = strtod (input, &ptr);
267 ASSERT (result == 0.0);
268 ASSERT (!signbit (result));
269 ASSERT (ptr == input + 2);
270 ASSERT (errno == 0);
273 const char input[] = "0e0";
274 char *ptr;
275 double result;
276 errno = 0;
277 result = strtod (input, &ptr);
278 ASSERT (result == 0.0);
279 ASSERT (!signbit (result));
280 ASSERT (ptr == input + 3);
281 ASSERT (errno == 0);
284 const char input[] = "0e+9999999";
285 char *ptr;
286 double result;
287 errno = 0;
288 result = strtod (input, &ptr);
289 ASSERT (result == 0.0);
290 ASSERT (!signbit (result));
291 ASSERT (ptr == input + 10);
292 ASSERT (errno == 0);
295 const char input[] = "0e-9999999";
296 char *ptr;
297 double result;
298 errno = 0;
299 result = strtod (input, &ptr);
300 ASSERT (result == 0.0);
301 ASSERT (!signbit (result));
302 ASSERT (ptr == input + 10);
303 ASSERT (errno == 0);
306 const char input[] = "-0";
307 char *ptr;
308 double result;
309 errno = 0;
310 result = strtod (input, &ptr);
311 ASSERT (result == 0.0);
312 ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* IRIX 6.5, OSF/1 4.0 */
313 ASSERT (ptr == input + 2);
314 ASSERT (errno == 0);
317 /* Suffixes. */
319 const char input[] = "1f";
320 char *ptr;
321 double result;
322 errno = 0;
323 result = strtod (input, &ptr);
324 ASSERT (result == 1.0);
325 ASSERT (ptr == input + 1);
326 ASSERT (errno == 0);
329 const char input[] = "1.f";
330 char *ptr;
331 double result;
332 errno = 0;
333 result = strtod (input, &ptr);
334 ASSERT (result == 1.0);
335 ASSERT (ptr == input + 2);
336 ASSERT (errno == 0);
339 const char input[] = "1e";
340 char *ptr;
341 double result;
342 errno = 0;
343 result = strtod (input, &ptr);
344 ASSERT (result == 1.0);
345 ASSERT (ptr == input + 1);
346 ASSERT (errno == 0);
349 const char input[] = "1e+";
350 char *ptr;
351 double result;
352 errno = 0;
353 result = strtod (input, &ptr);
354 ASSERT (result == 1.0);
355 ASSERT (ptr == input + 1);
356 ASSERT (errno == 0);
359 const char input[] = "1e-";
360 char *ptr;
361 double result;
362 errno = 0;
363 result = strtod (input, &ptr);
364 ASSERT (result == 1.0);
365 ASSERT (ptr == input + 1);
366 ASSERT (errno == 0);
369 const char input[] = "1E 2";
370 char *ptr;
371 double result;
372 errno = 0;
373 result = strtod (input, &ptr);
374 ASSERT (result == 1.0); /* HP-UX 11.11, IRIX 6.5, OSF/1 4.0 */
375 ASSERT (ptr == input + 1); /* HP-UX 11.11, IRIX 6.5 */
376 ASSERT (errno == 0);
379 const char input[] = "0x";
380 char *ptr;
381 double result;
382 errno = 0;
383 result = strtod (input, &ptr);
384 ASSERT (result == 0.0);
385 ASSERT (!signbit (result));
386 ASSERT (ptr == input + 1); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
387 ASSERT (errno == 0);
390 const char input[] = "00x1";
391 char *ptr;
392 double result;
393 errno = 0;
394 result = strtod (input, &ptr);
395 ASSERT (result == 0.0);
396 ASSERT (!signbit (result));
397 ASSERT (ptr == input + 2);
398 ASSERT (errno == 0);
401 const char input[] = "-0x";
402 char *ptr;
403 double result;
404 errno = 0;
405 result = strtod (input, &ptr);
406 ASSERT (result == 0.0);
407 ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* Mac OS X 10.3, FreeBSD 6.2, IRIX 6.5, OSF/1 4.0 */
408 ASSERT (ptr == input + 2); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
409 ASSERT (errno == 0);
412 const char input[] = "0xg";
413 char *ptr;
414 double result;
415 errno = 0;
416 result = strtod (input, &ptr);
417 ASSERT (result == 0.0);
418 ASSERT (!signbit (result));
419 ASSERT (ptr == input + 1); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
420 ASSERT (errno == 0);
423 const char input[] = "0xp";
424 char *ptr;
425 double result;
426 errno = 0;
427 result = strtod (input, &ptr);
428 ASSERT (result == 0.0);
429 ASSERT (!signbit (result));
430 ASSERT (ptr == input + 1); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
431 ASSERT (errno == 0);
434 const char input[] = "0XP";
435 char *ptr;
436 double result;
437 errno = 0;
438 result = strtod (input, &ptr);
439 ASSERT (result == 0.0);
440 ASSERT (!signbit (result));
441 ASSERT (ptr == input + 1); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
442 ASSERT (errno == 0);
445 const char input[] = "0x.";
446 char *ptr;
447 double result;
448 errno = 0;
449 result = strtod (input, &ptr);
450 ASSERT (result == 0.0);
451 ASSERT (!signbit (result));
452 ASSERT (ptr == input + 1); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
453 ASSERT (errno == 0);
456 const char input[] = "0xp+";
457 char *ptr;
458 double result;
459 errno = 0;
460 result = strtod (input, &ptr);
461 ASSERT (result == 0.0);
462 ASSERT (!signbit (result));
463 ASSERT (ptr == input + 1); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
464 ASSERT (errno == 0);
467 const char input[] = "0xp+1";
468 char *ptr;
469 double result;
470 errno = 0;
471 result = strtod (input, &ptr);
472 ASSERT (result == 0.0);
473 ASSERT (!signbit (result));
474 ASSERT (ptr == input + 1); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
475 ASSERT (errno == 0);
478 const char input[] = "0x.p+1";
479 char *ptr;
480 double result;
481 errno = 0;
482 result = strtod (input, &ptr);
483 ASSERT (result == 0.0);
484 ASSERT (!signbit (result));
485 ASSERT (ptr == input + 1); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
486 ASSERT (errno == 0);
489 const char input[] = "1p+1";
490 char *ptr;
491 double result;
492 errno = 0;
493 result = strtod (input, &ptr);
494 ASSERT (result == 1.0);
495 ASSERT (ptr == input + 1);
496 ASSERT (errno == 0);
499 const char input[] = "1P+1";
500 char *ptr;
501 double result;
502 errno = 0;
503 result = strtod (input, &ptr);
504 ASSERT (result == 1.0);
505 ASSERT (ptr == input + 1);
506 ASSERT (errno == 0);
509 /* Overflow/underflow. */
511 const char input[] = "1E1000000";
512 char *ptr;
513 double result;
514 errno = 0;
515 result = strtod (input, &ptr);
516 ASSERT (result == HUGE_VAL);
517 ASSERT (ptr == input + 9); /* OSF/1 5.1 */
518 ASSERT (errno == ERANGE);
521 const char input[] = "-1E1000000";
522 char *ptr;
523 double result;
524 errno = 0;
525 result = strtod (input, &ptr);
526 ASSERT (result == -HUGE_VAL);
527 ASSERT (ptr == input + 10);
528 ASSERT (errno == ERANGE);
531 const char input[] = "1E-100000";
532 char *ptr;
533 double result;
534 errno = 0;
535 result = strtod (input, &ptr);
536 ASSERT (0.0 <= result && result <= DBL_MIN);
537 ASSERT (!signbit (result));
538 ASSERT (ptr == input + 9);
539 ASSERT (errno == ERANGE);
542 const char input[] = "-1E-100000";
543 char *ptr;
544 double result;
545 errno = 0;
546 result = strtod (input, &ptr);
547 ASSERT (-DBL_MIN <= result && result <= 0.0);
548 #if 0
549 /* FIXME - this is glibc bug 5995; POSIX allows returning positive
550 0 on negative underflow, even though quality of implementation
551 demands preserving the sign. Disable this test until fixed
552 glibc is more prevalent. */
553 ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* glibc-2.3.6, mingw */
554 #endif
555 ASSERT (ptr == input + 10);
556 ASSERT (errno == ERANGE);
559 const char input[] = "1E 1000000";
560 char *ptr;
561 double result;
562 errno = 0;
563 result = strtod (input, &ptr);
564 ASSERT (result == 1.0); /* HP-UX 11.11, IRIX 6.5, OSF/1 4.0 */
565 ASSERT (ptr == input + 1); /* HP-UX 11.11, IRIX 6.5 */
566 ASSERT (errno == 0);
569 const char input[] = "0x1P 1000000";
570 char *ptr;
571 double result;
572 errno = 0;
573 result = strtod (input, &ptr);
574 ASSERT (result == 1.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
575 ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
576 ASSERT (errno == 0);
579 /* Infinity. */
581 const char input[] = "iNf";
582 char *ptr;
583 double result;
584 errno = 0;
585 result = strtod (input, &ptr);
586 ASSERT (result == HUGE_VAL); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
587 ASSERT (ptr == input + 3); /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw */
588 ASSERT (errno == 0); /* HP-UX 11.11, OSF/1 4.0 */
591 const char input[] = "-InF";
592 char *ptr;
593 double result;
594 errno = 0;
595 result = strtod (input, &ptr);
596 ASSERT (result == -HUGE_VAL); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
597 ASSERT (ptr == input + 4); /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 4.0, Solaris 9, mingw */
598 ASSERT (errno == 0); /* HP-UX 11.11, OSF/1 4.0 */
601 const char input[] = "infinite";
602 char *ptr;
603 double result;
604 errno = 0;
605 result = strtod (input, &ptr);
606 ASSERT (result == HUGE_VAL); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
607 ASSERT (ptr == input + 3); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
608 ASSERT (errno == 0); /* OSF/1 4.0 */
611 const char input[] = "infinitY";
612 char *ptr;
613 double result;
614 errno = 0;
615 result = strtod (input, &ptr);
616 ASSERT (result == HUGE_VAL); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
617 ASSERT (ptr == input + 8); /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw */
618 ASSERT (errno == 0); /* HP-UX 11.11, OSF/1 4.0 */
621 const char input[] = "infinitY.";
622 char *ptr;
623 double result;
624 errno = 0;
625 result = strtod (input, &ptr);
626 ASSERT (result == HUGE_VAL); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
627 ASSERT (ptr == input + 8); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
628 ASSERT (errno == 0); /* OSF/1 4.0 */
631 /* NaN. Some processors set the sign bit of the default NaN, so all
632 we check is that using a sign changes the result. */
634 const char input[] = "-nan";
635 char *ptr1;
636 char *ptr2;
637 double result1;
638 double result2;
639 errno = 0;
640 result1 = strtod (input, &ptr1);
641 result2 = strtod (input + 1, &ptr2);
642 #if 1 /* All known CPUs support NaNs. */
643 ASSERT (isnand (result1)); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
644 ASSERT (isnand (result2)); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
645 # if 0
646 /* Sign bits of NaN is a portability sticking point, not worth
647 worrying about. */
648 ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
649 # endif
650 ASSERT (ptr1 == input + 4); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
651 ASSERT (ptr2 == input + 4); /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
652 ASSERT (errno == 0); /* HP-UX 11.11 */
653 #else
654 ASSERT (result1 == 0.0);
655 ASSERT (result2 == 0.0);
656 ASSERT (!signbit (result1));
657 ASSERT (!signbit (result2));
658 ASSERT (ptr1 == input);
659 ASSERT (ptr2 == input + 1);
660 ASSERT (errno == 0 || errno == EINVAL);
661 #endif
664 const char input[] = "+nan(";
665 char *ptr1;
666 char *ptr2;
667 double result1;
668 double result2;
669 errno = 0;
670 result1 = strtod (input, &ptr1);
671 result2 = strtod (input + 1, &ptr2);
672 #if 1 /* All known CPUs support NaNs. */
673 ASSERT (isnand (result1)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
674 ASSERT (isnand (result2)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
675 ASSERT (!!signbit (result1) == !!signbit (result2));
676 ASSERT (ptr1 == input + 4); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
677 ASSERT (ptr2 == input + 4); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
678 ASSERT (errno == 0);
679 #else
680 ASSERT (result1 == 0.0);
681 ASSERT (result2 == 0.0);
682 ASSERT (!signbit (result1));
683 ASSERT (!signbit (result2));
684 ASSERT (ptr1 == input);
685 ASSERT (ptr2 == input + 1);
686 ASSERT (errno == 0 || errno == EINVAL);
687 #endif
690 const char input[] = "-nan()";
691 char *ptr1;
692 char *ptr2;
693 double result1;
694 double result2;
695 errno = 0;
696 result1 = strtod (input, &ptr1);
697 result2 = strtod (input + 1, &ptr2);
698 #if 1 /* All known CPUs support NaNs. */
699 ASSERT (isnand (result1)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
700 ASSERT (isnand (result2)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
701 # if 0
702 /* Sign bits of NaN is a portability sticking point, not worth
703 worrying about. */
704 ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
705 # endif
706 ASSERT (ptr1 == input + 6); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
707 ASSERT (ptr2 == input + 6); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
708 ASSERT (errno == 0);
709 #else
710 ASSERT (result1 == 0.0);
711 ASSERT (result2 == 0.0);
712 ASSERT (!signbit (result1));
713 ASSERT (!signbit (result2));
714 ASSERT (ptr1 == input);
715 ASSERT (ptr2 == input + 1);
716 ASSERT (errno == 0 || errno == EINVAL);
717 #endif
720 const char input[] = " nan().";
721 char *ptr;
722 double result;
723 errno = 0;
724 result = strtod (input, &ptr);
725 #if 1 /* All known CPUs support NaNs. */
726 ASSERT (isnand (result)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
727 ASSERT (ptr == input + 6); /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
728 ASSERT (errno == 0);
729 #else
730 ASSERT (result == 0.0);
731 ASSERT (!signbit (result));
732 ASSERT (ptr == input);
733 ASSERT (errno == 0 || errno == EINVAL);
734 #endif
737 /* The behavior of nan(0) is implementation-defined, but all
738 implementations we know of which handle optional
739 n-char-sequences handle nan(0) the same as nan(). */
740 const char input[] = "-nan(0).";
741 char *ptr1;
742 char *ptr2;
743 double result1;
744 double result2;
745 errno = 0;
746 result1 = strtod (input, &ptr1);
747 result2 = strtod (input + 1, &ptr2);
748 #if 1 /* All known CPUs support NaNs. */
749 ASSERT (isnand (result1)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
750 ASSERT (isnand (result2)); /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
751 # if 0
752 /* Sign bits of NaN is a portability sticking point, not worth
753 worrying about. */
754 ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
755 # endif
756 ASSERT (ptr1 == input + 7); /* glibc-2.3.6, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
757 ASSERT (ptr2 == input + 7); /* glibc-2.3.6, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
758 ASSERT (errno == 0);
759 #else
760 ASSERT (result1 == 0.0);
761 ASSERT (result2 == 0.0);
762 ASSERT (!signbit (result1));
763 ASSERT (!signbit (result2));
764 ASSERT (ptr1 == input);
765 ASSERT (ptr2 == input + 1);
766 ASSERT (errno == 0 || errno == EINVAL);
767 #endif
770 /* Hex. */
772 const char input[] = "0xa";
773 char *ptr;
774 double result;
775 errno = 0;
776 result = strtod (input, &ptr);
777 ASSERT (result == 10.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
778 ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
779 ASSERT (errno == 0);
782 const char input[] = "0XA";
783 char *ptr;
784 double result;
785 errno = 0;
786 result = strtod (input, &ptr);
787 ASSERT (result == 10.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
788 ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
789 ASSERT (errno == 0);
792 const char input[] = "0x1p";
793 char *ptr;
794 double result;
795 errno = 0;
796 result = strtod (input, &ptr);
797 ASSERT (result == 1.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
798 ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
799 ASSERT (errno == 0);
802 const char input[] = "0x1p+";
803 char *ptr;
804 double result;
805 errno = 0;
806 result = strtod (input, &ptr);
807 ASSERT (result == 1.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
808 ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
809 ASSERT (errno == 0);
812 const char input[] = "0x1P+";
813 char *ptr;
814 double result;
815 errno = 0;
816 result = strtod (input, &ptr);
817 ASSERT (result == 1.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
818 ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
819 ASSERT (errno == 0);
822 const char input[] = "0x1p+1";
823 char *ptr;
824 double result;
825 errno = 0;
826 result = strtod (input, &ptr);
827 ASSERT (result == 2.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
828 ASSERT (ptr == input + 6); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
829 ASSERT (errno == 0);
832 const char input[] = "0X1P+1";
833 char *ptr;
834 double result;
835 errno = 0;
836 result = strtod (input, &ptr);
837 ASSERT (result == 2.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
838 ASSERT (ptr == input + 6); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
839 ASSERT (errno == 0);
842 const char input[] = "0x1p+1a";
843 char *ptr;
844 double result;
845 errno = 0;
846 result = strtod (input, &ptr);
847 ASSERT (result == 2.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
848 ASSERT (ptr == input + 6); /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
849 ASSERT (errno == 0);
852 const char input[] = "0x1p 2";
853 char *ptr;
854 double result;
855 errno = 0;
856 result = strtod (input, &ptr);
857 ASSERT (result == 1.0); /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
858 ASSERT (ptr == input + 3); /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
859 ASSERT (errno == 0);
862 /* Large buffers. */
864 size_t m = 1000000;
865 char *input = malloc (m + 1);
866 if (input)
868 char *ptr;
869 double result;
870 memset (input, '\t', m - 1);
871 input[m - 1] = '1';
872 input[m] = '\0';
873 errno = 0;
874 result = strtod (input, &ptr);
875 ASSERT (result == 1.0);
876 ASSERT (ptr == input + m);
877 ASSERT (errno == 0);
879 free (input);
882 size_t m = 1000000;
883 char *input = malloc (m + 1);
884 if (input)
886 char *ptr;
887 double result;
888 memset (input, '0', m - 1);
889 input[m - 1] = '1';
890 input[m] = '\0';
891 errno = 0;
892 result = strtod (input, &ptr);
893 ASSERT (result == 1.0);
894 ASSERT (ptr == input + m);
895 ASSERT (errno == 0);
897 free (input);
899 #if 0
900 /* Newlib has an artificial limit of 20000 for the exponent. TODO -
901 gnulib should fix this. */
903 size_t m = 1000000;
904 char *input = malloc (m + 1);
905 if (input)
907 char *ptr;
908 double result;
909 input[0] = '.';
910 memset (input + 1, '0', m - 10);
911 input[m - 9] = '1';
912 input[m - 8] = 'e';
913 input[m - 7] = '+';
914 input[m - 6] = '9';
915 input[m - 5] = '9';
916 input[m - 4] = '9';
917 input[m - 3] = '9';
918 input[m - 2] = '9';
919 input[m - 1] = '1';
920 input[m] = '\0';
921 errno = 0;
922 result = strtod (input, &ptr);
923 ASSERT (result == 1.0); /* Mac OS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
924 ASSERT (ptr == input + m); /* OSF/1 5.1 */
925 ASSERT (errno == 0); /* Mac OS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
927 free (input);
930 size_t m = 1000000;
931 char *input = malloc (m + 1);
932 if (input)
934 char *ptr;
935 double result;
936 input[0] = '1';
937 memset (input + 1, '0', m - 9);
938 input[m - 8] = 'e';
939 input[m - 7] = '-';
940 input[m - 6] = '9';
941 input[m - 5] = '9';
942 input[m - 4] = '9';
943 input[m - 3] = '9';
944 input[m - 2] = '9';
945 input[m - 1] = '1';
946 input[m] = '\0';
947 errno = 0;
948 result = strtod (input, &ptr);
949 ASSERT (result == 1.0); /* Mac OS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
950 ASSERT (ptr == input + m);
951 ASSERT (errno == 0); /* Mac OS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
953 free (input);
955 #endif
957 size_t m = 1000000;
958 char *input = malloc (m + 1);
959 if (input)
961 char *ptr;
962 double result;
963 input[0] = '-';
964 input[1] = '0';
965 input[2] = 'e';
966 input[3] = '1';
967 memset (input + 4, '0', m - 3);
968 input[m] = '\0';
969 errno = 0;
970 result = strtod (input, &ptr);
971 ASSERT (result == 0.0);
972 ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* IRIX 6.5, OSF/1 4.0 */
973 ASSERT (ptr == input + m);
974 ASSERT (errno == 0);
976 free (input);
979 /* Rounding. */
980 /* TODO - is it worth some tests of rounding for typical IEEE corner
981 cases, such as .5 ULP rounding up to the smallest denormal and
982 not causing underflow, or DBL_MIN - .5 ULP not causing an
983 infinite loop? */
985 return status;