test-strtod: fix typos: s/abs/fabs/
[gnulib.git] / tests / test-strtod.c
1 /*
2  * Copyright (C) 2008 Free Software Foundation
3  * Written by Eric Blake
4  *
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.
9  *
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.
14  *
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/>.  */
17
18 #include <config.h>
19
20 #include <stdlib.h>
21
22 #include <errno.h>
23 #include <float.h>
24 #include <math.h>
25 #include <stdio.h>
26 #include <string.h>
27
28 #include "isnand.h"
29
30 #define ASSERT(expr) \
31   do                                                                         \
32     {                                                                        \
33       if (!(expr))                                                           \
34         {                                                                    \
35           fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
36           fflush (stderr);                                                   \
37           /* FIXME abort ();*/status = 1;                               \
38         }                                                                    \
39     }                                                                        \
40   while (0)
41
42 int
43 main ()
44 {
45   int status = 0;
46   /* Subject sequence empty or invalid.  */
47   {
48     const char input[] = "";
49     char *ptr;
50     double result;
51     errno = 0;
52     result = strtod (input, &ptr);
53     ASSERT (result == 0.0);
54     ASSERT (!signbit (result));
55     ASSERT (ptr == input);
56     ASSERT (errno == 0 || errno == EINVAL);
57   }
58   {
59     const char input[] = " ";
60     char *ptr;
61     double result;
62     errno = 0;
63     result = strtod (input, &ptr);
64     ASSERT (result == 0.0);
65     ASSERT (!signbit (result));
66     ASSERT (ptr == input);
67     ASSERT (errno == 0 || errno == EINVAL);
68   }
69   {
70     const char input[] = " +";
71     char *ptr;
72     double result;
73     errno = 0;
74     result = strtod (input, &ptr);
75     ASSERT (result == 0.0);
76     ASSERT (!signbit (result));
77     ASSERT (ptr == input);
78     ASSERT (errno == 0 || errno == EINVAL);
79   }
80   {
81     const char input[] = " .";
82     char *ptr;
83     double result;
84     errno = 0;
85     result = strtod (input, &ptr);
86     ASSERT (result == 0.0);
87     ASSERT (!signbit (result));
88     ASSERT (ptr == input);
89     ASSERT (errno == 0 || errno == EINVAL);
90   }
91   {
92     const char input[] = " .e0";
93     char *ptr;
94     double result;
95     errno = 0;
96     result = strtod (input, &ptr);
97     ASSERT (result == 0.0);
98     ASSERT (!signbit (result));
99     ASSERT (ptr == input);              /* IRIX 6.5, OSF/1 5.1 */
100     ASSERT (errno == 0 || errno == EINVAL);
101   }
102   {
103     const char input[] = " +.e-0";
104     char *ptr;
105     double result;
106     errno = 0;
107     result = strtod (input, &ptr);
108     ASSERT (result == 0.0);
109     ASSERT (!signbit (result));
110     ASSERT (ptr == input);              /* IRIX 6.5, OSF/1 5.1 */
111     ASSERT (errno == 0 || errno == EINVAL);
112   }
113   {
114     const char input[] = " in";
115     char *ptr;
116     double result;
117     errno = 0;
118     result = strtod (input, &ptr);
119     ASSERT (result == 0.0);
120     ASSERT (!signbit (result));
121     ASSERT (ptr == input);
122     ASSERT (errno == 0 || errno == EINVAL);
123   }
124   {
125     const char input[] = " na";
126     char *ptr;
127     double result;
128     errno = 0;
129     result = strtod (input, &ptr);
130     ASSERT (result == 0.0);
131     ASSERT (!signbit (result));
132     ASSERT (ptr == input);
133     ASSERT (errno == 0 || errno == EINVAL);
134   }
135
136   /* Simple floating point values.  */
137   {
138     const char input[] = "1";
139     char *ptr;
140     double result;
141     errno = 0;
142     result = strtod (input, &ptr);
143     ASSERT (result == 1.0);
144     ASSERT (ptr == input + 1);
145     ASSERT (errno == 0);
146   }
147   {
148     const char input[] = "1.";
149     char *ptr;
150     double result;
151     errno = 0;
152     result = strtod (input, &ptr);
153     ASSERT (result == 1.0);
154     ASSERT (ptr == input + 2);
155     ASSERT (errno == 0);
156   }
157   {
158     const char input[] = ".5";
159     char *ptr;
160     double result;
161     errno = 0;
162     result = strtod (input, &ptr);
163     /* FIXME - gnulib's version is rather inaccurate.  It would be
164        nice to guarantee an exact result, but for now, we settle for a
165        1-ulp error.  */
166     ASSERT (fabs (result - 0.5) < DBL_EPSILON);
167     ASSERT (ptr == input + 2);
168     ASSERT (errno == 0);
169   }
170   {
171     const char input[] = " 1";
172     char *ptr;
173     double result;
174     errno = 0;
175     result = strtod (input, &ptr);
176     ASSERT (result == 1.0);
177     ASSERT (ptr == input + 2);
178     ASSERT (errno == 0);
179   }
180   {
181     const char input[] = "+1";
182     char *ptr;
183     double result;
184     errno = 0;
185     result = strtod (input, &ptr);
186     ASSERT (result == 1.0);
187     ASSERT (ptr == input + 2);
188     ASSERT (errno == 0);
189   }
190   {
191     const char input[] = "-1";
192     char *ptr;
193     double result;
194     errno = 0;
195     result = strtod (input, &ptr);
196     ASSERT (result == -1.0);
197     ASSERT (ptr == input + 2);
198     ASSERT (errno == 0);
199   }
200   {
201     const char input[] = "1e0";
202     char *ptr;
203     double result;
204     errno = 0;
205     result = strtod (input, &ptr);
206     ASSERT (result == 1.0);
207     ASSERT (ptr == input + 3);
208     ASSERT (errno == 0);
209   }
210   {
211     const char input[] = "1e+0";
212     char *ptr;
213     double result;
214     errno = 0;
215     result = strtod (input, &ptr);
216     ASSERT (result == 1.0);
217     ASSERT (ptr == input + 4);
218     ASSERT (errno == 0);
219   }
220   {
221     const char input[] = "1e-0";
222     char *ptr;
223     double result;
224     errno = 0;
225     result = strtod (input, &ptr);
226     ASSERT (result == 1.0);
227     ASSERT (ptr == input + 4);
228     ASSERT (errno == 0);
229   }
230   {
231     const char input[] = "1e1";
232     char *ptr;
233     double result;
234     errno = 0;
235     result = strtod (input, &ptr);
236     ASSERT (result == 10.0);
237     ASSERT (ptr == input + 3);
238     ASSERT (errno == 0);
239   }
240   {
241     const char input[] = "5e-1";
242     char *ptr;
243     double result;
244     errno = 0;
245     result = strtod (input, &ptr);
246     /* FIXME - gnulib's version is rather inaccurate.  It would be
247        nice to guarantee an exact result, but for now, we settle for a
248        1-ulp error.  */
249     ASSERT (fabs (result - 0.5) < DBL_EPSILON);
250     ASSERT (ptr == input + 4);
251     ASSERT (errno == 0);
252   }
253
254   /* Zero.  */
255   {
256     const char input[] = "0";
257     char *ptr;
258     double result;
259     errno = 0;
260     result = strtod (input, &ptr);
261     ASSERT (result == 0.0);
262     ASSERT (!signbit (result));
263     ASSERT (ptr == input + 1);
264     ASSERT (errno == 0);
265   }
266   {
267     const char input[] = ".0";
268     char *ptr;
269     double result;
270     errno = 0;
271     result = strtod (input, &ptr);
272     ASSERT (result == 0.0);
273     ASSERT (!signbit (result));
274     ASSERT (ptr == input + 2);
275     ASSERT (errno == 0);
276   }
277   {
278     const char input[] = "0e0";
279     char *ptr;
280     double result;
281     errno = 0;
282     result = strtod (input, &ptr);
283     ASSERT (result == 0.0);
284     ASSERT (!signbit (result));
285     ASSERT (ptr == input + 3);
286     ASSERT (errno == 0);
287   }
288   {
289     const char input[] = "0e+9999999";
290     char *ptr;
291     double result;
292     errno = 0;
293     result = strtod (input, &ptr);
294     ASSERT (result == 0.0);
295     ASSERT (!signbit (result));
296     ASSERT (ptr == input + 10);
297     ASSERT (errno == 0);
298   }
299   {
300     const char input[] = "0e-9999999";
301     char *ptr;
302     double result;
303     errno = 0;
304     result = strtod (input, &ptr);
305     ASSERT (result == 0.0);
306     ASSERT (!signbit (result));
307     ASSERT (ptr == input + 10);
308     ASSERT (errno == 0);
309   }
310   {
311     const char input[] = "-0";
312     char *ptr;
313     double result;
314     errno = 0;
315     result = strtod (input, &ptr);
316     ASSERT (result == 0.0);
317     ASSERT (!!signbit (result) == !!signbit (-0.0)); /* IRIX 6.5, OSF/1 4.0 */
318     ASSERT (ptr == input + 2);
319     ASSERT (errno == 0);
320   }
321
322   /* Suffixes.  */
323   {
324     const char input[] = "1f";
325     char *ptr;
326     double result;
327     errno = 0;
328     result = strtod (input, &ptr);
329     ASSERT (result == 1.0);
330     ASSERT (ptr == input + 1);
331     ASSERT (errno == 0);
332   }
333   {
334     const char input[] = "1.f";
335     char *ptr;
336     double result;
337     errno = 0;
338     result = strtod (input, &ptr);
339     ASSERT (result == 1.0);
340     ASSERT (ptr == input + 2);
341     ASSERT (errno == 0);
342   }
343   {
344     const char input[] = "1e";
345     char *ptr;
346     double result;
347     errno = 0;
348     result = strtod (input, &ptr);
349     ASSERT (result == 1.0);
350     ASSERT (ptr == input + 1);
351     ASSERT (errno == 0);
352   }
353   {
354     const char input[] = "1e+";
355     char *ptr;
356     double result;
357     errno = 0;
358     result = strtod (input, &ptr);
359     ASSERT (result == 1.0);
360     ASSERT (ptr == input + 1);
361     ASSERT (errno == 0);
362   }
363   {
364     const char input[] = "1e-";
365     char *ptr;
366     double result;
367     errno = 0;
368     result = strtod (input, &ptr);
369     ASSERT (result == 1.0);
370     ASSERT (ptr == input + 1);
371     ASSERT (errno == 0);
372   }
373   {
374     const char input[] = "1E 2";
375     char *ptr;
376     double result;
377     errno = 0;
378     result = strtod (input, &ptr);
379     ASSERT (result == 1.0);             /* HP-UX 11.11, IRIX 6.5, OSF/1 4.0 */
380     ASSERT (ptr == input + 1);          /* HP-UX 11.11, IRIX 6.5 */
381     ASSERT (errno == 0);
382   }
383   {
384     const char input[] = "0x";
385     char *ptr;
386     double result;
387     errno = 0;
388     result = strtod (input, &ptr);
389     ASSERT (result == 0.0);
390     ASSERT (!signbit (result));
391     ASSERT (ptr == input + 1);          /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
392     ASSERT (errno == 0);
393   }
394   {
395     const char input[] = "00x1";
396     char *ptr;
397     double result;
398     errno = 0;
399     result = strtod (input, &ptr);
400     ASSERT (result == 0.0);
401     ASSERT (!signbit (result));
402     ASSERT (ptr == input + 2);
403     ASSERT (errno == 0);
404   }
405   {
406     const char input[] = "-0x";
407     char *ptr;
408     double result;
409     errno = 0;
410     result = strtod (input, &ptr);
411     ASSERT (result == 0.0);
412     ASSERT (!!signbit (result) == !!signbit (-0.0)); /* MacOS X 10.3, FreeBSD 6.2, IRIX 6.5, OSF/1 4.0 */
413     ASSERT (ptr == input + 2);          /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
414     ASSERT (errno == 0);
415   }
416   {
417     const char input[] = "0xg";
418     char *ptr;
419     double result;
420     errno = 0;
421     result = strtod (input, &ptr);
422     ASSERT (result == 0.0);
423     ASSERT (!signbit (result));
424     ASSERT (ptr == input + 1);          /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
425     ASSERT (errno == 0);
426   }
427   {
428     const char input[] = "0xp";
429     char *ptr;
430     double result;
431     errno = 0;
432     result = strtod (input, &ptr);
433     ASSERT (result == 0.0);
434     ASSERT (!signbit (result));
435     ASSERT (ptr == input + 1);          /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
436     ASSERT (errno == 0);
437   }
438   {
439     const char input[] = "0x.";
440     char *ptr;
441     double result;
442     errno = 0;
443     result = strtod (input, &ptr);
444     ASSERT (result == 0.0);
445     ASSERT (!signbit (result));
446     ASSERT (ptr == input + 1);          /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
447     ASSERT (errno == 0);
448   }
449   {
450     const char input[] = "0xp+";
451     char *ptr;
452     double result;
453     errno = 0;
454     result = strtod (input, &ptr);
455     ASSERT (result == 0.0);
456     ASSERT (!signbit (result));
457     ASSERT (ptr == input + 1);          /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
458     ASSERT (errno == 0);
459   }
460   {
461     const char input[] = "0xp+1";
462     char *ptr;
463     double result;
464     errno = 0;
465     result = strtod (input, &ptr);
466     ASSERT (result == 0.0);
467     ASSERT (!signbit (result));
468     ASSERT (ptr == input + 1);          /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
469     ASSERT (errno == 0);
470   }
471   {
472     const char input[] = "0x.p+1";
473     char *ptr;
474     double result;
475     errno = 0;
476     result = strtod (input, &ptr);
477     ASSERT (result == 0.0);
478     ASSERT (!signbit (result));
479     ASSERT (ptr == input + 1);          /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2 */
480     ASSERT (errno == 0);
481   }
482   {
483     const char input[] = "1p+1";
484     char *ptr;
485     double result;
486     errno = 0;
487     result = strtod (input, &ptr);
488     ASSERT (result == 1.0);
489     ASSERT (ptr == input + 1);
490     ASSERT (errno == 0);
491   }
492
493   /* Overflow/underflow.  */
494   {
495     const char input[] = "1E1000000";
496     char *ptr;
497     double result;
498     errno = 0;
499     result = strtod (input, &ptr);
500     ASSERT (result == HUGE_VAL);
501     ASSERT (ptr == input + 9);          /* OSF/1 5.1 */
502     ASSERT (errno == ERANGE);
503   }
504   {
505     const char input[] = "-1E1000000";
506     char *ptr;
507     double result;
508     errno = 0;
509     result = strtod (input, &ptr);
510     ASSERT (result == -HUGE_VAL);
511     ASSERT (ptr == input + 10);
512     ASSERT (errno == ERANGE);
513   }
514   {
515     const char input[] = "1E-100000";
516     char *ptr;
517     double result;
518     errno = 0;
519     result = strtod (input, &ptr);
520     ASSERT (0.0 <= result && result <= DBL_MIN);
521     ASSERT (!signbit (result));
522     ASSERT (ptr == input + 9);
523     ASSERT (errno == ERANGE);
524   }
525   {
526     const char input[] = "-1E-100000";
527     char *ptr;
528     double result;
529     errno = 0;
530     result = strtod (input, &ptr);
531     ASSERT (-DBL_MIN <= result && result <= 0.0);
532 #if 0
533     /* FIXME - this is glibc bug 5995; POSIX allows returning positive
534        0 on negative underflow, even though quality of implementation
535        demands preserving the sign.  Disable this test until fixed
536        glibc is more prevalent.  */
537     ASSERT (!!signbit (result) == !!signbit (-0.0)); /* glibc-2.3.6, mingw */
538 #endif
539     ASSERT (ptr == input + 10);
540     ASSERT (errno == ERANGE);
541   }
542
543   /* Infinity.  */
544   {
545     const char input[] = "iNf";
546     char *ptr;
547     double result;
548     errno = 0;
549     result = strtod (input, &ptr);
550     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
551     ASSERT (ptr == input + 3);          /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw */
552     ASSERT (errno == 0);                /* HP-UX 11.11, OSF/1 4.0 */
553   }
554   {
555     const char input[] = "-InF";
556     char *ptr;
557     double result;
558     errno = 0;
559     result = strtod (input, &ptr);
560     ASSERT (result == -HUGE_VAL);       /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
561     ASSERT (ptr == input + 4);          /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 4.0, Solaris 9, mingw */
562     ASSERT (errno == 0);                /* HP-UX 11.11, OSF/1 4.0 */
563   }
564   {
565     const char input[] = "infinite";
566     char *ptr;
567     double result;
568     errno = 0;
569     result = strtod (input, &ptr);
570     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
571     ASSERT (ptr == input + 3);          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
572     ASSERT (errno == 0);                /* OSF/1 4.0 */
573   }
574   {
575     const char input[] = "infinitY";
576     char *ptr;
577     double result;
578     errno = 0;
579     result = strtod (input, &ptr);
580     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
581     ASSERT (ptr == input + 8);          /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw */
582     ASSERT (errno == 0);                /* HP-UX 11.11, OSF/1 4.0 */
583   }
584   {
585     const char input[] = "infinitY.";
586     char *ptr;
587     double result;
588     errno = 0;
589     result = strtod (input, &ptr);
590     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
591     ASSERT (ptr == input + 8);          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
592     ASSERT (errno == 0);                /* OSF/1 4.0 */
593   }
594
595   /* NaN.  Some processors set the sign bit of the default NaN, so all
596      we check is that using a sign changes the result.  */
597   {
598     const char input[] = "-nan";
599     char *ptr1;
600     char *ptr2;
601     double result1;
602     double result2;
603     errno = 0;
604     result1 = strtod (input, &ptr1);
605     result2 = strtod (input + 1, &ptr2);
606 #if 1 /* All known CPUs support NaNs.  */
607     ASSERT (isnand (result1));          /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
608     ASSERT (isnand (result2));          /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
609 # if 0
610     /* Sign bits of NaN is a portability sticking point, not worth
611        worrying about.  */
612     ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
613 # endif
614     ASSERT (ptr1 == input + 4);         /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
615     ASSERT (ptr2 == input + 4);         /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
616     ASSERT (errno == 0);                /* HP-UX 11.11 */
617 #else
618     ASSERT (result1 == 0.0);
619     ASSERT (result2 == 0.0);
620     ASSERT (!signbit (result1));
621     ASSERT (!signbit (result2));
622     ASSERT (ptr1 == input);
623     ASSERT (ptr2 == input + 1);
624     ASSERT (errno == 0 || errno == EINVAL);
625 #endif
626   }
627   {
628     const char input[] = "+nan(";
629     char *ptr1;
630     char *ptr2;
631     double result1;
632     double result2;
633     errno = 0;
634     result1 = strtod (input, &ptr1);
635     result2 = strtod (input + 1, &ptr2);
636 #if 1 /* All known CPUs support NaNs.  */
637     ASSERT (isnand (result1));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
638     ASSERT (isnand (result2));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
639     ASSERT (!!signbit (result1) == !!signbit (result2));
640     ASSERT (ptr1 == input + 4);         /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
641     ASSERT (ptr2 == input + 4);         /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
642     ASSERT (errno == 0);
643 #else
644     ASSERT (result1 == 0.0);
645     ASSERT (result2 == 0.0);
646     ASSERT (!signbit (result1));
647     ASSERT (!signbit (result2));
648     ASSERT (ptr1 == input);
649     ASSERT (ptr2 == input + 1);
650     ASSERT (errno == 0 || errno == EINVAL);
651 #endif
652   }
653   {
654     const char input[] = "-nan()";
655     char *ptr1;
656     char *ptr2;
657     double result1;
658     double result2;
659     errno = 0;
660     result1 = strtod (input, &ptr1);
661     result2 = strtod (input + 1, &ptr2);
662 #if 1 /* All known CPUs support NaNs.  */
663     ASSERT (isnand (result1));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
664     ASSERT (isnand (result2));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
665 # if 0
666     /* Sign bits of NaN is a portability sticking point, not worth
667        worrying about.  */
668     ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
669 # endif
670     ASSERT (ptr1 == input + 6);         /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
671     ASSERT (ptr2 == input + 6);         /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
672     ASSERT (errno == 0);
673 #else
674     ASSERT (result1 == 0.0);
675     ASSERT (result2 == 0.0);
676     ASSERT (!signbit (result1));
677     ASSERT (!signbit (result2));
678     ASSERT (ptr1 == input);
679     ASSERT (ptr2 == input + 1);
680     ASSERT (errno == 0 || errno == EINVAL);
681 #endif
682   }
683   {
684     const char input[] = " nan().";
685     char *ptr;
686     double result;
687     errno = 0;
688     result = strtod (input, &ptr);
689 #if 1 /* All known CPUs support NaNs.  */
690     ASSERT (isnand (result));           /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
691     ASSERT (ptr == input + 6);          /* glibc-2.3.6, MacOS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
692     ASSERT (errno == 0);
693 #else
694     ASSERT (result == 0.0);
695     ASSERT (!signbit (result));
696     ASSERT (ptr == input);
697     ASSERT (errno == 0 || errno == EINVAL);
698 #endif
699   }
700   {
701     /* The behavior of nan(0) is implementation-defined, but all
702        implementations we know of which handle optional
703        n-char-sequences handle nan(0) the same as nan().  */
704     const char input[] = "-nan(0).";
705     char *ptr1;
706     char *ptr2;
707     double result1;
708     double result2;
709     errno = 0;
710     result1 = strtod (input, &ptr1);
711     result2 = strtod (input + 1, &ptr2);
712 #if 1 /* All known CPUs support NaNs.  */
713     ASSERT (isnand (result1));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
714     ASSERT (isnand (result2));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
715 # if 0
716     /* Sign bits of NaN is a portability sticking point, not worth
717        worrying about.  */
718     ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
719 # endif
720     ASSERT (ptr1 == input + 7);         /* glibc-2.3.6, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
721     ASSERT (ptr2 == input + 7);         /* glibc-2.3.6, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
722     ASSERT (errno == 0);
723 #else
724     ASSERT (result1 == 0.0);
725     ASSERT (result2 == 0.0);
726     ASSERT (!signbit (result1));
727     ASSERT (!signbit (result2));
728     ASSERT (ptr1 == input);
729     ASSERT (ptr2 == input + 1);
730     ASSERT (errno == 0 || errno == EINVAL);
731 #endif
732   }
733
734   /* Hex.  */
735   {
736     const char input[] = "0xa";
737     char *ptr;
738     double result;
739     errno = 0;
740     result = strtod (input, &ptr);
741     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 */
742     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 */
743     ASSERT (errno == 0);
744   }
745   {
746     const char input[] = "0XA";
747     char *ptr;
748     double result;
749     errno = 0;
750     result = strtod (input, &ptr);
751     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 */
752     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 */
753     ASSERT (errno == 0);
754   }
755   {
756     const char input[] = "0x1p";
757     char *ptr;
758     double result;
759     errno = 0;
760     result = strtod (input, &ptr);
761     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 */
762     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 */
763     ASSERT (errno == 0);
764   }
765   {
766     const char input[] = "0x1p+";
767     char *ptr;
768     double result;
769     errno = 0;
770     result = strtod (input, &ptr);
771     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 */
772     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 */
773     ASSERT (errno == 0);
774   }
775   {
776     const char input[] = "0x1p+1";
777     char *ptr;
778     double result;
779     errno = 0;
780     result = strtod (input, &ptr);
781     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 */
782     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 */
783     ASSERT (errno == 0);
784   }
785   {
786     const char input[] = "0x1p+1a";
787     char *ptr;
788     double result;
789     errno = 0;
790     result = strtod (input, &ptr);
791     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 */
792     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 */
793     ASSERT (errno == 0);
794   }
795
796   /* Large buffers.  */
797   {
798     size_t m = 1000000;
799     char *input = malloc (m + 1);
800     if (input)
801       {
802         char *ptr;
803         double result;
804         memset (input, '\t', m - 1);
805         input[m - 1] = '1';
806         input[m] = '\0';
807         errno = 0;
808         result = strtod (input, &ptr);
809         ASSERT (result == 1.0);
810         ASSERT (ptr == input + m);
811         ASSERT (errno == 0);
812       }
813     free (input);
814   }
815   {
816     size_t m = 1000000;
817     char *input = malloc (m + 1);
818     if (input)
819       {
820         char *ptr;
821         double result;
822         memset (input, '0', m - 1);
823         input[m - 1] = '1';
824         input[m] = '\0';
825         errno = 0;
826         result = strtod (input, &ptr);
827         ASSERT (result == 1.0);
828         ASSERT (ptr == input + m);
829         ASSERT (errno == 0);
830       }
831     free (input);
832   }
833 #if 0
834   /* Newlib has an artificial limit of 20000 for the exponent.  TODO -
835      gnulib should fix this.  */
836   {
837     size_t m = 1000000;
838     char *input = malloc (m + 1);
839     if (input)
840       {
841         char *ptr;
842         double result;
843         input[0] = '.';
844         memset (input + 1, '0', m - 10);
845         input[m - 9] = '1';
846         input[m - 8] = 'e';
847         input[m - 7] = '+';
848         input[m - 6] = '9';
849         input[m - 5] = '9';
850         input[m - 4] = '9';
851         input[m - 3] = '9';
852         input[m - 2] = '9';
853         input[m - 1] = '1';
854         input[m] = '\0';
855         errno = 0;
856         result = strtod (input, &ptr);
857         ASSERT (result == 1.0);         /* MacOS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
858         ASSERT (ptr == input + m);      /* OSF/1 5.1 */
859         ASSERT (errno == 0);            /* MacOS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
860       }
861     free (input);
862   }
863   {
864     size_t m = 1000000;
865     char *input = malloc (m + 1);
866     if (input)
867       {
868         char *ptr;
869         double result;
870         input[0] = '1';
871         memset (input + 1, '0', m - 9);
872         input[m - 8] = 'e';
873         input[m - 7] = '-';
874         input[m - 6] = '9';
875         input[m - 5] = '9';
876         input[m - 4] = '9';
877         input[m - 3] = '9';
878         input[m - 2] = '9';
879         input[m - 1] = '1';
880         input[m] = '\0';
881         errno = 0;
882         result = strtod (input, &ptr);
883         ASSERT (result == 1.0);         /* MacOS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
884         ASSERT (ptr == input + m);
885         ASSERT (errno == 0);            /* MacOS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
886       }
887     free (input);
888   }
889 #endif
890   {
891     size_t m = 1000000;
892     char *input = malloc (m + 1);
893     if (input)
894       {
895         char *ptr;
896         double result;
897         input[0] = '-';
898         input[1] = '0';
899         input[2] = 'e';
900         input[3] = '1';
901         memset (input + 4, '0', m - 3);
902         input[m] = '\0';
903         errno = 0;
904         result = strtod (input, &ptr);
905         ASSERT (result == 0.0);
906         ASSERT (!!signbit (result) == !!signbit (-0.0)); /* IRIX 6.5, OSF/1 4.0 */
907         ASSERT (ptr == input + m);
908         ASSERT (errno == 0);
909       }
910     free (input);
911   }
912
913   /* Rounding.  */
914   /* TODO - is it worth some tests of rounding for typical IEEE corner
915      cases, such as .5 ULP rounding up to the smallest denormal and
916      not causing underflow, or DBL_MIN - .5 ULP not causing an
917      infinite loop?  */
918
919   return status;
920 }