c54a8fda73d8f3ec7df37809fcfaf208ffdad03b
[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[] = ".1";
147     char *ptr;
148     double result = strtod (input, &ptr);
149     ASSERT (result == 0.1);
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[] = "1e-1";
219     char *ptr;
220     double result = strtod (input, &ptr);
221     ASSERT (result == 0.1);
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[] = "0x";
337     char *ptr;
338     double result = strtod (input, &ptr);
339     ASSERT (result == 0.0);
340     ASSERT (!signbit (result));
341     ASSERT (ptr == input + 1);
342     ASSERT (errno == 0);
343   }
344   {
345     errno = 0;
346     const char input[] = "00x1";
347     char *ptr;
348     double result = strtod (input, &ptr);
349     ASSERT (result == 0.0);
350     ASSERT (!signbit (result));
351     ASSERT (ptr == input + 2);
352     ASSERT (errno == 0);
353   }
354   {
355     errno = 0;
356     const char input[] = "-0x";
357     char *ptr;
358     double result = strtod (input, &ptr);
359     ASSERT (result == 0.0);
360     ASSERT (signbit (result) == signbit (-0.0));
361     ASSERT (ptr == input + 2);
362     ASSERT (errno == 0);
363   }
364   {
365     errno = 0;
366     const char input[] = "0xg";
367     char *ptr;
368     double result = strtod (input, &ptr);
369     ASSERT (result == 0.0);
370     ASSERT (!signbit (result));
371     ASSERT (ptr == input + 1);
372     ASSERT (errno == 0);
373   }
374   {
375     errno = 0;
376     const char input[] = "0xp";
377     char *ptr;
378     double result = strtod (input, &ptr);
379     ASSERT (result == 0.0);
380     ASSERT (!signbit (result));
381     ASSERT (ptr == input + 1);
382     ASSERT (errno == 0);
383   }
384   {
385     errno = 0;
386     const char input[] = "0x.";
387     char *ptr;
388     double result = strtod (input, &ptr);
389     ASSERT (result == 0.0);
390     ASSERT (!signbit (result));
391     ASSERT (ptr == input + 1);
392     ASSERT (errno == 0);
393   }
394   {
395     errno = 0;
396     const char input[] = "0xp+";
397     char *ptr;
398     double result = strtod (input, &ptr);
399     ASSERT (result == 0.0);
400     ASSERT (!signbit (result));
401     ASSERT (ptr == input + 1);
402     ASSERT (errno == 0);
403   }
404   {
405     errno = 0;
406     const char input[] = "0xp+1";
407     char *ptr;
408     double result = strtod (input, &ptr);
409     ASSERT (result == 0.0);
410     ASSERT (!signbit (result));
411     ASSERT (ptr == input + 1);
412     ASSERT (errno == 0);
413   }
414   {
415     errno = 0;
416     const char input[] = "0x.p+1";
417     char *ptr;
418     double result = strtod (input, &ptr);
419     ASSERT (result == 0.0);
420     ASSERT (!signbit (result));
421     ASSERT (ptr == input + 1);
422     ASSERT (errno == 0);
423   }
424   {
425     errno = 0;
426     const char input[] = "1p+1";
427     char *ptr;
428     double result = strtod (input, &ptr);
429     ASSERT (result == 1.0);
430     ASSERT (ptr == input + 1);
431     ASSERT (errno == 0);
432   }
433
434   /* Overflow/underflow.  */
435   {
436     errno = 0;
437     const char input[] = "1E100000";
438     char *ptr;
439     double result = strtod (input, &ptr);
440     ASSERT (result == HUGE_VAL);
441     ASSERT (ptr == input + 8);
442     ASSERT (errno == ERANGE);
443   }
444   {
445     errno = 0;
446     const char input[] = "-1E100000";
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[] = "1E-100000";
456     char *ptr;
457     double result = strtod (input, &ptr);
458     ASSERT (0.0 <= result && result <= FLT_MIN);
459     ASSERT (!signbit (result));
460     ASSERT (ptr == input + 9);
461     ASSERT (errno == ERANGE);
462   }
463   {
464     errno = 0;
465     const char input[] = "-1E-100000";
466     char *ptr;
467     double result = strtod (input, &ptr);
468     ASSERT (-FLT_MIN <= result && result <= 0.0);
469     ASSERT (signbit (result) == signbit (-0.0));
470     ASSERT (ptr == input + 10);
471     ASSERT (errno == ERANGE);
472   }
473
474   /* Infinity.  */
475   {
476     errno = 0;
477     const char input[] = "iNf";
478     char *ptr;
479     double result = strtod (input, &ptr);
480     ASSERT (result == HUGE_VAL);
481     ASSERT (ptr == input + 3);
482     ASSERT (errno == 0);
483   }
484   {
485     errno = 0;
486     const char input[] = "-InF";
487     char *ptr;
488     double result = strtod (input, &ptr);
489     ASSERT (result == -HUGE_VAL);
490     ASSERT (ptr == input + 4);
491     ASSERT (errno == 0);
492   }
493   {
494     errno = 0;
495     const char input[] = "infinite";
496     char *ptr;
497     double result = strtod (input, &ptr);
498     ASSERT (result == HUGE_VAL);
499     ASSERT (ptr == input + 3);
500     ASSERT (errno == 0);
501   }
502   {
503     errno = 0;
504     const char input[] = "infinitY";
505     char *ptr;
506     double result = strtod (input, &ptr);
507     ASSERT (result == HUGE_VAL);
508     ASSERT (ptr == input + 8);
509     ASSERT (errno == 0);
510   }
511   {
512     errno = 0;
513     const char input[] = "infinitY.";
514     char *ptr;
515     double result = strtod (input, &ptr);
516     ASSERT (result == HUGE_VAL);
517     ASSERT (ptr == input + 8);
518     ASSERT (errno == 0);
519   }
520
521   /* NaN.  Some processors set the sign bit of the default NaN, so all
522      we check is that using a sign changes the result.  */
523   {
524     errno = 0;
525     const char input[] = "-nan";
526     char *ptr1;
527     char *ptr2;
528     double result1 = strtod (input, &ptr1);
529     double result2 = strtod (input + 1, &ptr2);
530 #ifdef NAN
531     ASSERT (isnan (result1));
532     ASSERT (isnan (result2));
533     ASSERT (signbit (result1) != signbit (result2));
534     ASSERT (ptr1 == input + 4);
535     ASSERT (ptr2 == input + 4);
536     ASSERT (errno == 0);
537 #else
538     ASSERT (result1 == 0.0);
539     ASSERT (result2 == 0.0);
540     ASSERT (!signbit (result1));
541     ASSERT (!signbit (result2));
542     ASSERT (ptr1 == input);
543     ASSERT (ptr2 == input + 1);
544     ASSERT (errno == 0 || errno == EINVAL);
545 #endif
546   }
547   {
548     errno = 0;
549     const char input[] = "+nan(";
550     char *ptr1;
551     char *ptr2;
552     double result1 = strtod (input, &ptr1);
553     double result2 = strtod (input + 1, &ptr2);
554 #ifdef NAN
555     ASSERT (isnan (result1));
556     ASSERT (isnan (result2));
557     ASSERT (signbit (result1) == signbit (result2));
558     ASSERT (ptr1 == input + 4);
559     ASSERT (ptr2 == input + 4);
560     ASSERT (errno == 0);
561 #else
562     ASSERT (result1 == 0.0);
563     ASSERT (result2 == 0.0);
564     ASSERT (!signbit (result1));
565     ASSERT (!signbit (result2));
566     ASSERT (ptr1 == input);
567     ASSERT (ptr2 == input + 1);
568     ASSERT (errno == 0 || errno == EINVAL);
569 #endif
570   }
571   {
572     errno = 0;
573     const char input[] = "-nan()";
574     char *ptr1;
575     char *ptr2;
576     double result1 = strtod (input, &ptr1);
577     double result2 = strtod (input + 1, &ptr2);
578 #ifdef NAN
579     ASSERT (isnan (result1));
580     ASSERT (isnan (result2));
581     ASSERT (signbit (result1) != signbit (result2));
582     ASSERT (ptr1 == input + 6);
583     ASSERT (ptr2 == input + 6);
584     ASSERT (errno == 0);
585 #else
586     ASSERT (result1 == 0.0);
587     ASSERT (result2 == 0.0);
588     ASSERT (!signbit (result1));
589     ASSERT (!signbit (result2));
590     ASSERT (ptr1 == input);
591     ASSERT (ptr2 == input + 1);
592     ASSERT (errno == 0 || errno == EINVAL);
593 #endif
594   }
595   {
596     errno = 0;
597     const char input[] = " nan().";
598     char *ptr;
599     double result = strtod (input, &ptr);
600 #ifdef NAN
601     ASSERT (isnan (result));
602     ASSERT (ptr == input + 6);
603     ASSERT (errno == 0);
604 #else
605     ASSERT (result == 0.0);
606     ASSERT (!signbit (result));
607     ASSERT (ptr == input);
608     ASSERT (errno == 0 || errno == EINVAL);
609 #endif
610   }
611   {
612     errno = 0;
613     /* The behavior of nan(0) is implementation-defined, but all
614        implementations we know of which handle optional
615        n-char-sequences handle nan(0) the same as nan().  */
616     const char input[] = "-nan(0).";
617     char *ptr1;
618     char *ptr2;
619     double result1 = strtod (input, &ptr1);
620     double result2 = strtod (input + 1, &ptr2);
621 #ifdef NAN
622     ASSERT (isnan (result1));
623     ASSERT (isnan (result2));
624     ASSERT (signbit (result1) != signbit (result2));
625     ASSERT (ptr1 == input + 7);
626     ASSERT (ptr2 == input + 7);
627     ASSERT (errno == 0);
628 #else
629     ASSERT (result1 == 0.0);
630     ASSERT (result2 == 0.0);
631     ASSERT (!signbit (result1));
632     ASSERT (!signbit (result2));
633     ASSERT (ptr1 == input);
634     ASSERT (ptr2 == input + 1);
635     ASSERT (errno == 0 || errno == EINVAL);
636 #endif
637   }
638
639   /* Hex.  */
640 #if 0
641   /* TODO - gnulib doesn't implement this yet.  */
642   {
643     errno = 0;
644     const char input[] = "0xa";
645     char *ptr;
646     double result = strtod (input, &ptr);
647     ASSERT (result == 10.0);
648     ASSERT (ptr == input + 3);
649     ASSERT (errno == 0);
650   }
651   {
652     errno = 0;
653     const char input[] = "0XA";
654     char *ptr;
655     double result = strtod (input, &ptr);
656     ASSERT (result == 10.0);
657     ASSERT (ptr == input + 3);
658     ASSERT (errno == 0);
659   }
660   {
661     errno = 0;
662     const char input[] = "0x1p";
663     char *ptr;
664     double result = strtod (input, &ptr);
665     ASSERT (result == 1.0);
666     ASSERT (ptr == input + 3);
667     ASSERT (errno == 0);
668   }
669   {
670     errno = 0;
671     const char input[] = "0x1p+";
672     char *ptr;
673     double result = strtod (input, &ptr);
674     ASSERT (result == 1.0);
675     ASSERT (ptr == input + 3);
676     ASSERT (errno == 0);
677   }
678   {
679     errno = 0;
680     const char input[] = "0x1p+1";
681     char *ptr;
682     double result = strtod (input, &ptr);
683     ASSERT (result == 2.0);
684     ASSERT (ptr == input + 6);
685     ASSERT (errno == 0);
686   }
687   {
688     errno = 0;
689     const char input[] = "0x1p+1a";
690     char *ptr;
691     double result = strtod (input, &ptr);
692     ASSERT (result == 2.0);
693     ASSERT (ptr == input + 6);
694     ASSERT (errno == 0);
695   }
696 #endif
697
698   /* Large buffers.  */
699   {
700     errno = 0;
701     size_t m = 1000000;
702     char *input = malloc (m + 1);
703     if (input)
704       {
705         char *ptr;
706         double result;
707         memset (input, '\t', m - 1);
708         input[m - 1] = '1';
709         input[m] = '\0';
710         result = strtod (input, &ptr);
711         ASSERT (result == 1.0);
712         ASSERT (ptr == input + m);
713         ASSERT (errno == 0);
714       }
715     free (input);
716   }
717   {
718     errno = 0;
719     size_t m = 1000000;
720     char *input = malloc (m + 1);
721     if (input)
722       {
723         char *ptr;
724         double result;
725         memset (input, '0', m - 1);
726         input[m - 1] = '1';
727         input[m] = '\0';
728         result = strtod (input, &ptr);
729         ASSERT (result == 1.0);
730         ASSERT (ptr == input + m);
731         ASSERT (errno == 0);
732       }
733     free (input);
734   }
735 #if 0
736   /* Newlib has an artificial limit of 20000 for the exponent.  TODO -
737      gnulib should fix this.  */
738   {
739     errno = 0;
740     size_t m = 1000000;
741     char *input = malloc (m + 1);
742     if (input)
743       {
744         char *ptr;
745         double result;
746         input[0] = '.';
747         memset (input + 1, '0', m - 10);
748         input[m - 9] = '1';
749         input[m - 8] = 'e';
750         input[m - 7] = '+';
751         input[m - 6] = '9';
752         input[m - 5] = '9';
753         input[m - 4] = '9';
754         input[m - 3] = '9';
755         input[m - 2] = '9';
756         input[m - 1] = '1';
757         input[m] = '\0';
758         result = strtod (input, &ptr);
759         ASSERT (result == 1.0);
760         ASSERT (ptr == input + m);
761         ASSERT (errno == 0);
762       }
763     free (input);
764   }
765   {
766     errno = 0;
767     size_t m = 1000000;
768     char *input = malloc (m + 1);
769     if (input)
770       {
771         char *ptr;
772         double result;
773         input[0] = '1';
774         memset (input + 1, '0', m - 9);
775         input[m - 8] = 'e';
776         input[m - 7] = '-';
777         input[m - 6] = '9';
778         input[m - 5] = '9';
779         input[m - 4] = '9';
780         input[m - 3] = '9';
781         input[m - 2] = '9';
782         input[m - 1] = '1';
783         input[m] = '\0';
784         result = strtod (input, &ptr);
785         ASSERT (result == 1.0);
786         ASSERT (ptr == input + m);
787         ASSERT (errno == 0);
788       }
789     free (input);
790   }
791 #endif
792   {
793     errno = 0;
794     size_t m = 1000000;
795     char *input = malloc (m + 1);
796     if (input)
797       {
798         char *ptr;
799         double result;
800         input[0] = '-';
801         input[1] = '0';
802         input[2] = 'e';
803         input[3] = '1';
804         memset (input + 4, '0', m - 3);
805         input[m] = '\0';
806         result = strtod (input, &ptr);
807         ASSERT (result == 0.0);
808         ASSERT (signbit (result) == signbit (-0.0));
809         ASSERT (ptr == input + m);
810         ASSERT (errno == 0);
811       }
812     free (input);
813   }
814
815   /* Rounding.  */
816   /* TODO - is it worth some tests of rounding for typical IEEE corner
817      cases, such as .5 ULP rounding up to the smallest denormal and
818      not causing underflow, or FLT_MIN - .5 ULP not causing an
819      infinite loop?  */
820
821   return status;
822 }