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