probe_math_exception.c 1.4 KB

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