fenv.h 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #pragma once
  2. #include_next <fenv.h>
  3. #ifndef HAVE_FEENABLEEXCEPT
  4. #if defined(__APPLE__) && defined(__MACH__)
  5. // Public domain polyfill for feenableexcept on OS X
  6. // http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c
  7. inline int feenableexcept(unsigned int excepts)
  8. {
  9. static fenv_t fenv;
  10. unsigned int new_excepts = excepts & FE_ALL_EXCEPT;
  11. // previous masks
  12. unsigned int old_excepts;
  13. if (fegetenv(&fenv)) {
  14. return -1;
  15. }
  16. old_excepts = fenv.__control & FE_ALL_EXCEPT;
  17. // unmask
  18. fenv.__control &= ~new_excepts;
  19. fenv.__mxcsr &= ~(new_excepts << 7);
  20. return fesetenv(&fenv) ? -1 : old_excepts;
  21. }
  22. inline int fedisableexcept(unsigned int excepts)
  23. {
  24. static fenv_t fenv;
  25. unsigned int new_excepts = excepts & FE_ALL_EXCEPT;
  26. // all previous masks
  27. unsigned int old_excepts;
  28. if (fegetenv(&fenv)) {
  29. return -1;
  30. }
  31. old_excepts = fenv.__control & FE_ALL_EXCEPT;
  32. // mask
  33. fenv.__control |= new_excepts;
  34. fenv.__mxcsr |= new_excepts << 7;
  35. return fesetenv(&fenv) ? -1 : old_excepts;
  36. }
  37. #else
  38. inline int feenableexcept(unsigned int excepts)
  39. {
  40. #pragma STDC FENV_ACCESS ON
  41. fexcept_t flags;
  42. /* Save current exception flags. */
  43. fegetexceptflag(&flags, FE_ALL_EXCEPT);
  44. feclearexcept(FE_ALL_EXCEPT); /* clear all fp exception conditions */
  45. return fesetexceptflag(&flags, excepts) != 0 ? -1 : flags; /* set new flags */
  46. }
  47. inline int fedisableexcept(unsigned int excepts)
  48. {
  49. #pragma STDC FENV_ACCESS ON
  50. fexcept_t flags;
  51. /* Save current exception flags. */
  52. fegetexceptflag(&flags, FE_ALL_EXCEPT);
  53. feclearexcept(FE_ALL_EXCEPT); /* clear all fp exception conditions */
  54. return fesetexceptflag(&flags, ~excepts) != 0 ? -1 : flags; /* set new flags */
  55. }
  56. #endif
  57. #endif