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