OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / uClibc / docs / probe_math_exception.c
1 /* 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
13 int 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 }