1#include <fenv.h>
2#include <limits.h>
3#include <math.h>
4#include <stdint.h>
5#include <stdio.h>
6
7static void DivideByZero() {
8  // volatile to prevent compiler optimizations.
9  volatile float zero = 0.0f;
10  volatile float result __attribute__((unused)) = 123.0f / zero;
11}
12
13int main () {
14   /* Testing lrint. */
15   fesetround(FE_UPWARD); // lrint/lrintf/lrintl obey the rounding mode.
16   printf("fesetround(FE_UPWARD)\n");
17   printf("lrint(1234.01): %ld\n", lrint(1234.01));
18   printf("lrintf(1234.01f): %ld\n", lrintf(1234.01f));
19   printf("lrintl(1234.01): %ld\n", lrintl(1234.01));
20   fesetround(FE_TOWARDZERO); // lrint/lrintf/lrintl obey the rounding mode.
21   printf("fesetround(FE_TOWARDZERO)\n");
22   printf("lrint(1234.01): %ld\n", lrint(1234.01));
23   printf("lrintf(1234.01f): %ld\n", lrintf(1234.01f));
24   printf("lrintl(1234.01): %ld\n", lrintl(1234.01));
25   fesetround(FE_UPWARD); // llrint/llrintf/llrintl obey the rounding mode.
26   printf("fesetround(FE_UPWARD)\n");
27   printf("llrint(1234.01): %lld\n", llrint(1234.01));
28   printf("llrintf(1234.01f): %lld\n", llrintf(1234.01f));
29   printf("llrintf(1234.01f): %lld\n", llrintl(1234.01));
30   fesetround(FE_TOWARDZERO); // llrint/llrintf/llrintl obey the rounding mode.
31   printf("fesetround(FE_TOWARDZERO)\n");
32   printf("llrint(1234.01): %lld\n", llrint(1234.01));
33   printf("llrintf(1234.01f): %lld\n", llrintf(1234.01f));
34   printf("llrintl(1234.01): %lld\n", llrintl(1234.01));
35
36   /* Tesing rint. */
37   fesetround(FE_UPWARD); // rint/rintf/rintl obey the rounding mode.
38   printf("fesetround(FE_UPWARD)\n");
39   feclearexcept(FE_ALL_EXCEPT); // rint/rintf/rintl do set the FE_INEXACT flag.
40   printf("feclearexcept(FE_ALL_EXCEPT)\n");
41   printf("rint(1234.0): %f\n", rint(1234.0));
42   printf("(fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT): %d\n",
43           (fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT));
44   printf("rint(1234.01): %f\n", rint(1234.01));
45   printf("(fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT): %d\n",
46           (fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT));
47
48   feclearexcept(FE_ALL_EXCEPT); // rint/rintf/rintl do set the FE_INEXACT flag.
49   printf("feclearexcept(FE_ALL_EXCEPT)\n");
50   printf("rintf(1234.0f): %f\n", rintf(1234.0f));
51   printf("(fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT): %d\n",
52           (fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT));
53   printf("rintf(1234.01f): %f\n", rintf(1234.01f));
54   printf("(fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT): %d\n",
55           (fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT));
56
57   feclearexcept(FE_ALL_EXCEPT); // rint/rintf/rintl do set the FE_INEXACT flag.
58   printf("feclearexcept(FE_ALL_EXCEPT)\n");
59   printf("rintl(1234.0): %Lf\n", rintl(1234.0));
60   printf("(fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT): %d\n",
61           (fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT));
62   printf("rintl(1234.01): %Lf\n", rintl(1234.01));
63   printf("(fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT): %d\n",
64           (fetestexcept(FE_ALL_EXCEPT) & FE_INEXACT));
65
66   fesetround(FE_TOWARDZERO); // rint/rintf obey the rounding mode.
67   printf("fesetround(FE_TOWARDZERO)\n");
68   printf("rint(1234.01): %f\n", rint(1234.01));
69   printf("rintf(1234.01f): %f\n", rintf(1234.01f));
70   printf("rintl(1234.01): %Lf\n", rintl(1234.01));
71
72   /* Testing nearbyint. */
73   fesetround(FE_UPWARD); // nearbyint/nearbyintf/nearbyintl obey the rounding mode.
74   printf("fesetround(FE_UPWARD)\n");
75   feclearexcept(FE_ALL_EXCEPT); // nearbyint/nearbyintf/nearbyintl don't set the FE_INEXACT flag.
76   printf("feclearexcept(FE_ALL_EXCEPT)\n");
77   printf("nearbyint(1234.0): %f\n", nearbyint(1234.0));
78   printf("nearbyint(1234.01): %f\n", nearbyint(1234.01));
79
80   feclearexcept(FE_ALL_EXCEPT);
81   printf("feclearexcept(FE_ALL_EXCEPT)\n");
82   printf("nearbyintf(1234.0f): %f\n", nearbyintf(1234.0f));
83   printf("nearbyintf(1234.01f): %f\n", nearbyintf(1234.01f));
84
85   feclearexcept(FE_ALL_EXCEPT); // nearbyint/nearbyintf/nearbyintl don't set the FE_INEXACT flag.
86   printf("feclearexcept(FE_ALL_EXCEPT)\n");
87   printf("nearbyintl(1234.0f): %Lf\n", nearbyintl(1234.0f));
88   printf("nearbyintl(1234.01f): %Lf\n", nearbyintl(1234.01f));
89
90   fesetround(FE_TOWARDZERO); // nearbyint/nearbyintf/nearbyintl obey the rounding mode.
91   printf("fesetround(FE_TOWARDZERO)\n");
92   printf("nearbyint(1234.01): %f\n", nearbyint(1234.01));
93   printf("nearbyintf(1234.01f): %f\n", nearbyintf(1234.01f));
94   printf("nearbyintl(1234.01): %Lf\n", nearbyintl(1234.01));
95
96   /* Test log. */
97   printf("log(M_E): %lf\n", log(M_E));
98
99   /* Test tgamma. */
100   printf("tgamma(5.0): %lf\n", tgamma(5.0));
101
102   /* Test cbrt. */
103   printf("cbrt(27.0): %lf\n", cbrt(27.0));
104
105   /* Test dividing by zero. */
106   // Clearing clears.
107   printf("feclearexcept(FE_ALL_EXCEPT): %d\n", feclearexcept(FE_ALL_EXCEPT));
108
109   // Dividing by zero sets FE_DIVBYZERO.
110   DivideByZero();
111   int raised = fetestexcept(FE_DIVBYZERO | FE_OVERFLOW);
112   printf("raised: %d\n", raised);
113
114   return 0;
115}
116