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