Add another fma test.
[platform/upstream/glibc.git] / math / test-fenv.c
1 /* Copyright (C) 1997-2013 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Andreas Jaeger <aj@suse.de> and
4    Ulrich Drepper <drepper@cygnus.com>, 1997.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <http://www.gnu.org/licenses/>.  */
19
20 /* Tests for ISO C99 7.6: Floating-point environment  */
21
22 #ifndef _GNU_SOURCE
23 # define _GNU_SOURCE
24 #endif
25
26 #include <complex.h>
27 #include <math.h>
28 #include <float.h>
29 #include <fenv.h>
30
31 #include <errno.h>
32 #include <signal.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <sys/wait.h>
38 #include <sys/resource.h>
39
40 /*
41   Since not all architectures might define all exceptions, we define
42   a private set and map accordingly.
43 */
44 #define NO_EXC 0
45 #define INEXACT_EXC 0x1
46 #define DIVBYZERO_EXC 0x2
47 #define UNDERFLOW_EXC 0x04
48 #define OVERFLOW_EXC 0x08
49 #define INVALID_EXC 0x10
50 #define ALL_EXC \
51         (INEXACT_EXC | DIVBYZERO_EXC | UNDERFLOW_EXC | OVERFLOW_EXC | \
52          INVALID_EXC)
53
54 static int count_errors;
55
56 /* Test whether a given exception was raised.  */
57 static void
58 test_single_exception (short int exception,
59                        short int exc_flag,
60                        fexcept_t fe_flag,
61                        const char *flag_name)
62 {
63   if (exception & exc_flag)
64     {
65       if (fetestexcept (fe_flag))
66         printf ("  Pass: Exception \"%s\" is set\n", flag_name);
67       else
68         {
69           printf ("  Fail: Exception \"%s\" is not set\n", flag_name);
70           ++count_errors;
71         }
72     }
73   else
74     {
75       if (fetestexcept (fe_flag))
76         {
77           printf ("  Fail: Exception \"%s\" is set\n", flag_name);
78           ++count_errors;
79         }
80       else
81         {
82           printf ("  Pass: Exception \"%s\" is not set\n", flag_name);
83         }
84     }
85 }
86
87 static void
88 test_exceptions (const char *test_name, short int exception,
89                  int ignore_inexact)
90 {
91   printf ("Test: %s\n", test_name);
92 #ifdef FE_DIVBYZERO
93   test_single_exception (exception, DIVBYZERO_EXC, FE_DIVBYZERO,
94                          "DIVBYZERO");
95 #endif
96 #ifdef FE_INVALID
97   test_single_exception (exception, INVALID_EXC, FE_INVALID,
98                          "INVALID");
99 #endif
100 #ifdef FE_INEXACT
101   if (!ignore_inexact)
102     test_single_exception (exception, INEXACT_EXC, FE_INEXACT,
103                            "INEXACT");
104 #endif
105 #ifdef FE_UNDERFLOW
106   test_single_exception (exception, UNDERFLOW_EXC, FE_UNDERFLOW,
107                          "UNDERFLOW");
108 #endif
109 #ifdef FE_OVERFLOW
110   test_single_exception (exception, OVERFLOW_EXC, FE_OVERFLOW,
111                          "OVERFLOW");
112 #endif
113 }
114
115 static void
116 print_rounding (int rounding)
117 {
118
119   switch (rounding)
120     {
121 #ifdef FE_TONEAREST
122     case FE_TONEAREST:
123       printf ("TONEAREST");
124       break;
125 #endif
126 #ifdef FE_UPWARD
127     case FE_UPWARD:
128       printf ("UPWARD");
129       break;
130 #endif
131 #ifdef FE_DOWNWARD
132     case FE_DOWNWARD:
133       printf ("DOWNWARD");
134       break;
135 #endif
136 #ifdef FE_TOWARDZERO
137     case FE_TOWARDZERO:
138       printf ("TOWARDZERO");
139       break;
140 #endif
141     }
142   printf (".\n");
143 }
144
145
146 static void
147 test_rounding (const char *test_name, int rounding_mode)
148 {
149   int curr_rounding = fegetround ();
150
151   printf ("Test: %s\n", test_name);
152   if (curr_rounding == rounding_mode)
153     {
154       printf ("  Pass: Rounding mode is ");
155       print_rounding (curr_rounding);
156     }
157   else
158     {
159       ++count_errors;
160       printf ("  Fail: Rounding mode is ");
161       print_rounding (curr_rounding);
162     }
163 }
164
165
166 static void
167 set_single_exc (const char *test_name, int fe_exc, fexcept_t exception)
168 {
169   char str[200];
170   /* The standard allows the inexact exception to be set together with the
171      underflow and overflow exceptions.  So ignore the inexact flag if the
172      others are raised.  */
173   int ignore_inexact = (fe_exc & (UNDERFLOW_EXC | OVERFLOW_EXC)) != 0;
174
175   strcpy (str, test_name);
176   strcat (str, ": set flag, with rest not set");
177   feclearexcept (FE_ALL_EXCEPT);
178   feraiseexcept (exception);
179   test_exceptions (str, fe_exc, ignore_inexact);
180
181   strcpy (str, test_name);
182   strcat (str, ": clear flag, rest also unset");
183   feclearexcept (exception);
184   test_exceptions (str, NO_EXC, ignore_inexact);
185
186   strcpy (str, test_name);
187   strcat (str, ": set flag, with rest set");
188   feraiseexcept (FE_ALL_EXCEPT ^ exception);
189   feraiseexcept (exception);
190   test_exceptions (str, ALL_EXC, 0);
191
192   strcpy (str, test_name);
193   strcat (str, ": clear flag, leave rest set");
194   feclearexcept (exception);
195   test_exceptions (str, ALL_EXC ^ fe_exc, 0);
196 }
197
198 static void
199 fe_tests (void)
200 {
201   /* clear all exceptions and test if all are cleared */
202   feclearexcept (FE_ALL_EXCEPT);
203   test_exceptions ("feclearexcept (FE_ALL_EXCEPT) clears all exceptions",
204                    NO_EXC, 0);
205
206   /* raise all exceptions and test if all are raised */
207   feraiseexcept (FE_ALL_EXCEPT);
208   test_exceptions ("feraiseexcept (FE_ALL_EXCEPT) raises all exceptions",
209                    ALL_EXC, 0);
210   feclearexcept (FE_ALL_EXCEPT);
211
212 #ifdef FE_DIVBYZERO
213   set_single_exc ("Set/Clear FE_DIVBYZERO", DIVBYZERO_EXC, FE_DIVBYZERO);
214 #endif
215 #ifdef FE_INVALID
216   set_single_exc ("Set/Clear FE_INVALID", INVALID_EXC, FE_INVALID);
217 #endif
218 #ifdef FE_INEXACT
219   set_single_exc ("Set/Clear FE_INEXACT", INEXACT_EXC, FE_INEXACT);
220 #endif
221 #ifdef FE_UNDERFLOW
222   set_single_exc ("Set/Clear FE_UNDERFLOW", UNDERFLOW_EXC, FE_UNDERFLOW);
223 #endif
224 #ifdef FE_OVERFLOW
225   set_single_exc ("Set/Clear FE_OVERFLOW", OVERFLOW_EXC, FE_OVERFLOW);
226 #endif
227 }
228
229 /* Test that program aborts with no masked interrupts */
230 static void
231 feenv_nomask_test (const char *flag_name, int fe_exc)
232 {
233 #if defined FE_NOMASK_ENV
234   int status;
235   pid_t pid;
236   fenv_t saved;
237
238   fegetenv (&saved);
239   errno = 0;
240   fesetenv (FE_NOMASK_ENV);
241   status = errno;
242   fesetenv (&saved);
243   if (status == ENOSYS)
244     {
245       printf ("Test: not testing FE_NOMASK_ENV, it isn't implemented.\n");
246       return;
247     }
248
249   printf ("Test: after fesetenv (FE_NOMASK_ENV) processes will abort\n");
250   printf ("      when feraiseexcept (%s) is called.\n", flag_name);
251   pid = fork ();
252   if (pid == 0)
253     {
254 #ifdef RLIMIT_CORE
255       /* Try to avoid dumping core.  */
256       struct rlimit core_limit;
257       core_limit.rlim_cur = 0;
258       core_limit.rlim_max = 0;
259       setrlimit (RLIMIT_CORE, &core_limit);
260 #endif
261
262       fesetenv (FE_NOMASK_ENV);
263       feraiseexcept (fe_exc);
264       exit (2);
265     }
266   else if (pid < 0)
267     {
268       if (errno != ENOSYS)
269         {
270           printf ("  Fail: Could not fork.\n");
271           ++count_errors;
272         }
273       else
274         printf ("  `fork' not implemented, test ignored.\n");
275     }
276   else {
277     if (waitpid (pid, &status, 0) != pid)
278       {
279         printf ("  Fail: waitpid call failed.\n");
280         ++count_errors;
281       }
282     else if (WIFSIGNALED (status) && WTERMSIG (status) == SIGFPE)
283       printf ("  Pass: Process received SIGFPE.\n");
284     else
285       {
286         printf ("  Fail: Process didn't receive signal and exited with status %d.\n",
287                 status);
288         ++count_errors;
289       }
290   }
291 #endif
292 }
293
294 /* Test that program doesn't abort with default environment */
295 static void
296 feenv_mask_test (const char *flag_name, int fe_exc)
297 {
298   int status;
299   pid_t pid;
300
301   printf ("Test: after fesetenv (FE_DFL_ENV) processes will not abort\n");
302   printf ("      when feraiseexcept (%s) is called.\n", flag_name);
303   pid = fork ();
304   if (pid == 0)
305     {
306 #ifdef RLIMIT_CORE
307       /* Try to avoid dumping core.  */
308       struct rlimit core_limit;
309       core_limit.rlim_cur = 0;
310       core_limit.rlim_max = 0;
311       setrlimit (RLIMIT_CORE, &core_limit);
312 #endif
313
314       fesetenv (FE_DFL_ENV);
315       feraiseexcept (fe_exc);
316       exit (2);
317     }
318   else if (pid < 0)
319     {
320       if (errno != ENOSYS)
321         {
322           printf ("  Fail: Could not fork.\n");
323           ++count_errors;
324         }
325       else
326         printf ("  `fork' not implemented, test ignored.\n");
327     }
328   else {
329     if (waitpid (pid, &status, 0) != pid)
330       {
331         printf ("  Fail: waitpid call failed.\n");
332         ++count_errors;
333       }
334     else if (WIFEXITED (status) && WEXITSTATUS (status) == 2)
335       printf ("  Pass: Process exited normally.\n");
336     else
337       {
338         printf ("  Fail: Process exited abnormally with status %d.\n",
339                 status);
340         ++count_errors;
341       }
342   }
343 }
344
345 /* Test that program aborts with no masked interrupts */
346 static void
347 feexcp_nomask_test (const char *flag_name, int fe_exc)
348 {
349   int status;
350   pid_t pid;
351
352   printf ("Test: after fedisableexcept (%s) processes will abort\n",
353           flag_name);
354   printf ("      when feraiseexcept (%s) is called.\n", flag_name);
355   pid = fork ();
356   if (pid == 0)
357     {
358 #ifdef RLIMIT_CORE
359       /* Try to avoid dumping core.  */
360       struct rlimit core_limit;
361       core_limit.rlim_cur = 0;
362       core_limit.rlim_max = 0;
363       setrlimit (RLIMIT_CORE, &core_limit);
364 #endif
365
366       fedisableexcept (FE_ALL_EXCEPT);
367       feenableexcept (fe_exc);
368       feraiseexcept (fe_exc);
369       exit (2);
370     }
371   else if (pid < 0)
372     {
373       if (errno != ENOSYS)
374         {
375           printf ("  Fail: Could not fork.\n");
376           ++count_errors;
377         }
378       else
379         printf ("  `fork' not implemented, test ignored.\n");
380     }
381   else {
382     if (waitpid (pid, &status, 0) != pid)
383       {
384         printf ("  Fail: waitpid call failed.\n");
385         ++count_errors;
386       }
387     else if (WIFSIGNALED (status) && WTERMSIG (status) == SIGFPE)
388       printf ("  Pass: Process received SIGFPE.\n");
389     else
390       {
391         printf ("  Fail: Process didn't receive signal and exited with status %d.\n",
392                 status);
393         ++count_errors;
394       }
395   }
396 }
397
398 /* Test that program doesn't abort with exception.  */
399 static void
400 feexcp_mask_test (const char *flag_name, int fe_exc)
401 {
402   int status;
403   int exception;
404   pid_t pid;
405
406   printf ("Test: after fedisableexcept (%s) processes will not abort\n",
407           flag_name);
408   printf ("      when feraiseexcept (%s) is called.\n", flag_name);
409   pid = fork ();
410   if (pid == 0)
411     {
412 #ifdef RLIMIT_CORE
413       /* Try to avoid dumping core.  */
414       struct rlimit core_limit;
415       core_limit.rlim_cur = 0;
416       core_limit.rlim_max = 0;
417       setrlimit (RLIMIT_CORE, &core_limit);
418 #endif
419       feenableexcept (FE_ALL_EXCEPT);
420       exception = fe_exc;
421 #ifdef FE_INEXACT
422       /* The standard allows the inexact exception to be set together with the
423          underflow and overflow exceptions.  So add FE_INEXACT to the set of
424          exceptions to be disabled if we will be raising underflow or
425          overflow.  */
426 # ifdef FE_OVERFLOW
427       if (fe_exc & FE_OVERFLOW)
428         exception |= FE_INEXACT;
429 # endif
430 # ifdef FE_UNDERFLOW
431       if (fe_exc & FE_UNDERFLOW)
432         exception |= FE_INEXACT;
433 # endif
434 #endif
435       fedisableexcept (exception);
436       feraiseexcept (fe_exc);
437       exit (2);
438     }
439   else if (pid < 0)
440     {
441       if (errno != ENOSYS)
442         {
443           printf ("  Fail: Could not fork.\n");
444           ++count_errors;
445         }
446       else
447         printf ("  `fork' not implemented, test ignored.\n");
448     }
449   else {
450     if (waitpid (pid, &status, 0) != pid)
451       {
452         printf ("  Fail: waitpid call failed.\n");
453         ++count_errors;
454       }
455     else if (WIFEXITED (status) && WEXITSTATUS (status) == 2)
456       printf ("  Pass: Process exited normally.\n");
457     else
458       {
459         printf ("  Fail: Process exited abnormally with status %d.\n",
460                 status);
461         ++count_errors;
462       }
463   }
464 }
465
466
467 /* Tests for feenableexcept/fedisableexcept/fegetexcept.  */
468 static void
469 feenable_test (const char *flag_name, int fe_exc)
470 {
471   int excepts;
472
473
474   printf ("Tests for feenableexcepts etc. with flag %s\n", flag_name);
475
476   /* First disable all exceptions.  */
477   if (fedisableexcept (FE_ALL_EXCEPT) == -1)
478     {
479       printf ("Test: fedisableexcept (FE_ALL_EXCEPT) failed\n");
480       ++count_errors;
481       /* If this fails, the other tests don't make sense.  */
482       return;
483     }
484   excepts = fegetexcept ();
485   if (excepts != 0)
486     {
487       printf ("Test: fegetexcept (%s) failed, return should be 0, is %d\n",
488               flag_name, excepts);
489       ++count_errors;
490     }
491
492   excepts = feenableexcept (fe_exc);
493   if (excepts == -1)
494     {
495       printf ("Test: feenableexcept (%s) failed\n", flag_name);
496       ++count_errors;
497       return;
498     }
499   if (excepts != 0)
500     {
501       printf ("Test: feenableexcept (%s) failed, return should be 0, is %x\n",
502               flag_name, excepts);
503       ++count_errors;
504     }
505
506   excepts = fegetexcept ();
507   if (excepts != fe_exc)
508     {
509       printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
510               flag_name, fe_exc, excepts);
511       ++count_errors;
512     }
513
514   /* And now disable the exception again.  */
515   excepts = fedisableexcept (fe_exc);
516   if (excepts == -1)
517     {
518       printf ("Test: fedisableexcept (%s) failed\n", flag_name);
519       ++count_errors;
520       return;
521     }
522   if (excepts != fe_exc)
523     {
524       printf ("Test: fedisableexcept (%s) failed, return should be 0x%x, is 0x%x\n",
525               flag_name, fe_exc, excepts);
526       ++count_errors;
527     }
528
529   excepts = fegetexcept ();
530   if (excepts != 0)
531     {
532       printf ("Test: fegetexcept (%s) failed, return should be 0, is 0x%x\n",
533               flag_name, excepts);
534       ++count_errors;
535     }
536
537   /* Now the other way round: Enable all exceptions and disable just this one.  */
538   if (feenableexcept (FE_ALL_EXCEPT) == -1)
539     {
540       printf ("Test: feenableexcept (FE_ALL_EXCEPT) failed\n");
541       ++count_errors;
542       /* If this fails, the other tests don't make sense.  */
543       return;
544     }
545
546   excepts = fegetexcept ();
547   if (excepts != FE_ALL_EXCEPT)
548     {
549       printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
550               flag_name, FE_ALL_EXCEPT, excepts);
551       ++count_errors;
552     }
553
554   excepts = fedisableexcept (fe_exc);
555   if (excepts == -1)
556     {
557       printf ("Test: fedisableexcept (%s) failed\n", flag_name);
558       ++count_errors;
559       return;
560     }
561   if (excepts != FE_ALL_EXCEPT)
562     {
563       printf ("Test: fedisableexcept (%s) failed, return should be 0, is 0x%x\n",
564               flag_name, excepts);
565       ++count_errors;
566     }
567
568   excepts = fegetexcept ();
569   if (excepts != (FE_ALL_EXCEPT & ~fe_exc))
570     {
571       printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
572               flag_name, (FE_ALL_EXCEPT & ~fe_exc), excepts);
573       ++count_errors;
574     }
575
576   /* And now enable the exception again.  */
577   excepts = feenableexcept (fe_exc);
578   if (excepts == -1)
579     {
580       printf ("Test: feenableexcept (%s) failed\n", flag_name);
581       ++count_errors;
582       return;
583     }
584   if (excepts != (FE_ALL_EXCEPT & ~fe_exc))
585     {
586       printf ("Test: feenableexcept (%s) failed, return should be 0, is 0x%x\n",
587               flag_name, excepts);
588       ++count_errors;
589     }
590
591   excepts = fegetexcept ();
592   if (excepts != FE_ALL_EXCEPT)
593     {
594       printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
595               flag_name, FE_ALL_EXCEPT, excepts);
596       ++count_errors;
597     }
598   feexcp_nomask_test (flag_name, fe_exc);
599   feexcp_mask_test (flag_name, fe_exc);
600
601 }
602
603
604 static void
605 fe_single_test (const char *flag_name, int fe_exc)
606 {
607   feenv_nomask_test (flag_name, fe_exc);
608   feenv_mask_test (flag_name, fe_exc);
609   feenable_test (flag_name, fe_exc);
610 }
611
612
613 static void
614 feenv_tests (void)
615 {
616   /* We might have some exceptions still set.  */
617   feclearexcept (FE_ALL_EXCEPT);
618
619 #ifdef FE_DIVBYZERO
620   fe_single_test ("FE_DIVBYZERO", FE_DIVBYZERO);
621 #endif
622 #ifdef FE_INVALID
623   fe_single_test ("FE_INVALID", FE_INVALID);
624 #endif
625 #ifdef FE_INEXACT
626   fe_single_test ("FE_INEXACT", FE_INEXACT);
627 #endif
628 #ifdef FE_UNDERFLOW
629   fe_single_test ("FE_UNDERFLOW", FE_UNDERFLOW);
630 #endif
631 #ifdef FE_OVERFLOW
632   fe_single_test ("FE_OVERFLOW", FE_OVERFLOW);
633 #endif
634   fesetenv (FE_DFL_ENV);
635 }
636
637
638 static void
639 feholdexcept_tests (void)
640 {
641   fenv_t saved, saved2;
642   int res;
643
644   feclearexcept (FE_ALL_EXCEPT);
645   fedisableexcept (FE_ALL_EXCEPT);
646 #ifdef FE_DIVBYZERO
647   feraiseexcept (FE_DIVBYZERO);
648 #endif
649   test_exceptions ("feholdexcept_tests FE_DIVBYZERO test",
650                    DIVBYZERO_EXC, 0);
651   res = feholdexcept (&saved);
652   if (res != 0)
653     {
654       printf ("feholdexcept failed: %d\n", res);
655       ++count_errors;
656     }
657 #if defined FE_TONEAREST && defined FE_TOWARDZERO
658   res = fesetround (FE_TOWARDZERO);
659   if (res != 0)
660     {
661       printf ("fesetround failed: %d\n", res);
662       ++count_errors;
663     }
664 #endif
665   test_exceptions ("feholdexcept_tests 0 test", NO_EXC, 0);
666 #ifdef FE_INVALID
667   feraiseexcept (FE_INVALID);
668   test_exceptions ("feholdexcept_tests FE_INVALID test",
669                    INVALID_EXC, 0);
670 #endif
671   res = feupdateenv (&saved);
672   if (res != 0)
673     {
674       printf ("feupdateenv failed: %d\n", res);
675       ++count_errors;
676     }
677 #if defined FE_TONEAREST && defined FE_TOWARDZERO
678   res = fegetround ();
679   if (res != FE_TONEAREST)
680     {
681       printf ("feupdateenv didn't restore rounding mode: %d\n", res);
682       ++count_errors;
683     }
684 #endif
685   test_exceptions ("feholdexcept_tests FE_DIVBYZERO|FE_INVALID test",
686                    DIVBYZERO_EXC | INVALID_EXC, 0);
687   feclearexcept (FE_ALL_EXCEPT);
688 #ifdef FE_INVALID
689   feraiseexcept (FE_INVALID);
690 #endif
691 #if defined FE_TONEAREST && defined FE_UPWARD
692   res = fesetround (FE_UPWARD);
693   if (res != 0)
694     {
695       printf ("fesetround failed: %d\n", res);
696       ++count_errors;
697     }
698 #endif
699   res = feholdexcept (&saved2);
700   if (res != 0)
701     {
702       printf ("feholdexcept failed: %d\n", res);
703       ++count_errors;
704     }
705 #if defined FE_TONEAREST && defined FE_UPWARD
706   res = fesetround (FE_TONEAREST);
707   if (res != 0)
708     {
709       printf ("fesetround failed: %d\n", res);
710       ++count_errors;
711     }
712 #endif
713   test_exceptions ("feholdexcept_tests 0 2nd test", NO_EXC, 0);
714 #ifdef FE_INEXACT
715   feraiseexcept (FE_INEXACT);
716   test_exceptions ("feholdexcept_tests FE_INEXACT test",
717                    INEXACT_EXC, 0);
718 #endif
719   res = feupdateenv (&saved2);
720   if (res != 0)
721     {
722       printf ("feupdateenv failed: %d\n", res);
723       ++count_errors;
724     }
725 #if defined FE_TONEAREST && defined FE_UPWARD
726   res = fegetround ();
727   if (res != FE_UPWARD)
728     {
729       printf ("feupdateenv didn't restore rounding mode: %d\n", res);
730       ++count_errors;
731     }
732   fesetround (FE_TONEAREST);
733 #endif
734   test_exceptions ("feholdexcept_tests FE_INEXACT|FE_INVALID test",
735                    INVALID_EXC | INEXACT_EXC, 0);
736   feclearexcept (FE_ALL_EXCEPT);
737 }
738
739
740 /* IEC 559 and ISO C99 define a default startup environment */
741 static void
742 initial_tests (void)
743 {
744   test_exceptions ("Initially all exceptions should be cleared",
745                    NO_EXC, 0);
746 #ifdef FE_TONEAREST
747   test_rounding ("Rounding direction should be initalized to nearest",
748                  FE_TONEAREST);
749 #endif
750 }
751
752 int
753 main (void)
754 {
755   initial_tests ();
756   fe_tests ();
757   feenv_tests ();
758   feholdexcept_tests ();
759
760   if (count_errors)
761     {
762       printf ("\n%d errors occurred.\n", count_errors);
763       exit (1);
764     }
765   printf ("\n All tests passed successfully.\n");
766   return 0;
767 }