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