blob: dbc9020d4a16618289104dc8c2a5cee70bef400b [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* Small test program for probing how various math functions
2 * with specific operands set floating point exceptions
3 */
4
5#define _ISOC99_SOURCE 1
6#define _GNU_SOURCE 1
7
8#include <stdint.h>
9#include <math.h>
10#include <fenv.h>
11#include <stdio.h>
12
13int main(int argc, char **argv)
14{
15 float largest, small, t, inf_float;
16
17 largest = small = 1;
18 while (1) {
19 t = largest + small;
20 /* optimizations may make plain "t == largest" unreliable */
21 if (memcmp(&t, &largest, sizeof(float)) == 0)
22 break;
23 if (isfinite(t)) {
24 largest = t;
25 small *= 2;
26 continue;
27 }
28 small /= 2;
29 }
30 inf_float = largest + largest;
31 //printf("%.40g ", largest);
32 //printf("[%llx]\n", (long long) (*(uint32_t *)&largest));
33
34 feclearexcept(FE_ALL_EXCEPT);
35
36 //t = 1.0 / 0.0; // simple test: FE_DIVBYZERO
37 //t = nextafterf(largest, 1); // glibc 2.8: no math exceptions raised
38 //t = nextafterf(largest, largest); // glibc 2.8: no math exceptions raised
39 //t = nextafterf(largest, inf_float); // glibc 2.8: FE_INEXACT FE_OVERFLOW
40
41#define PREX(ex) do { if (fetestexcept(ex)) printf(#ex " "); } while(0)
42#ifdef FE_INEXACT
43 PREX(FE_INEXACT);
44#endif
45#ifdef FE_DIVBYZERO
46 PREX(FE_DIVBYZERO);
47#endif
48#ifdef FE_UNDERFLOW
49 PREX(FE_UNDERFLOW);
50#endif
51#ifdef FE_OVERFLOW
52 PREX(FE_OVERFLOW);
53#endif
54#ifdef FE_INVALID
55 PREX(FE_INVALID);
56#endif
57 if (fetestexcept(FE_ALL_EXCEPT))
58 printf("\n");
59 else
60 printf("no math exceptions raised\n");
61
62 printf("%.40g\n", t);
63 return 0;
64}