int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { int mode; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("HPUX PA-RISC only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("HPUX PA-RISC only supports default precision rounding", GSL_EUNSUP) ; break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("HPUX PA-RISC only supports default precision rounding", GSL_EUNSUP) ; break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: fesetround (FE_TONEAREST) ; break ; case GSL_IEEE_ROUND_DOWN: fesetround (FE_DOWNWARD) ; break ; case GSL_IEEE_ROUND_UP: fesetround (FE_UPWARD) ; break ; case GSL_IEEE_ROUND_TO_ZERO: fesetround (FE_TOWARDZERO) ; break ; default: fesetround (FE_TONEAREST) ; } /* Turn on all the exceptions apart from 'inexact' */ mode = FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW ; if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ FE_INVALID ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("HP-UX does not support the denormalized operand exception. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ FE_DIVBYZERO ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ FE_OVERFLOW ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ FE_UNDERFLOW ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode |= FE_INEXACT ; } else { mode &= ~ FE_INEXACT ; } fesettrapenable (mode) ; return GSL_SUCCESS ; }
int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { int mode; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: GSL_ERROR ("single precision rounding is not supported by <fenv.h>", GSL_EUNSUP) ; break ; case GSL_IEEE_DOUBLE_PRECISION: GSL_ERROR ("double precision rounding is not supported by <fenv.h>", GSL_EUNSUP) ; break ; case GSL_IEEE_EXTENDED_PRECISION: GSL_ERROR ("extended precision rounding is not supported by <fenv.h>", GSL_EUNSUP) ; break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: #ifdef FE_TONEAREST fesetround (FE_TONEAREST) ; #else GSL_ERROR ("round-to-nearest is not supported by <fenv.h>", GSL_EUNSUP) ; #endif break ; case GSL_IEEE_ROUND_DOWN: #ifdef FE_DOWNWARD fesetround (FE_DOWNWARD) ; #else GSL_ERROR ("round-down is not supported by <fenv.h>", GSL_EUNSUP) ; #endif break ; case GSL_IEEE_ROUND_UP: #ifdef FE_UPWARD fesetround (FE_UPWARD) ; #else GSL_ERROR ("round-up is not supported by <fenv.h>", GSL_EUNSUP) ; #endif break ; case GSL_IEEE_ROUND_TO_ZERO: #ifdef FE_TOWARDZERO fesetround (FE_TOWARDZERO) ; #else GSL_ERROR ("round-toward-zero is not supported by <fenv.h>", GSL_EUNSUP) ; #endif break ; default: #ifdef FE_TONEAREST fesetround (FE_TONEAREST) ; #else GSL_ERROR ("default round-to-nearest mode is not supported by <fenv.h>", GSL_EUNSUP) ; #endif } /* Turn on all the exceptions apart from 'inexact' */ mode = 0; #ifdef FE_INVALID mode |= FE_INVALID; #endif #ifdef FE_DIVBYZERO mode |= FE_DIVBYZERO; #endif #ifdef FE_OVERFLOW mode |= FE_OVERFLOW ; #endif #ifdef FE_UNDERFLOW mode |= FE_UNDERFLOW ; #endif if (exception_mask & GSL_IEEE_MASK_INVALID) { #ifdef FE_INVALID mode &= ~ FE_INVALID ; #else GSL_ERROR ("invalid operation exception not supported by <fenv.h>", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) { /* do nothing */ } else { GSL_ERROR ("denormalized operand exception not supported by <fenv.h>. " "Use 'mask-denormalized' to work around this.", GSL_EUNSUP) ; } if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) { #ifdef FE_DIVBYZERO mode &= ~ FE_DIVBYZERO ; #else GSL_ERROR ("division by zero exception not supported by <fenv.h>", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_MASK_OVERFLOW) { #ifdef FE_OVERFLOW mode &= ~ FE_OVERFLOW ; #else GSL_ERROR ("overflow exception not supported by <fenv.h>", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) { #ifdef FE_UNDERFLOW mode &= ~ FE_UNDERFLOW ; #else GSL_ERROR ("underflow exception not supported by <fenv.h>", GSL_EUNSUP); #endif } if (exception_mask & GSL_IEEE_TRAP_INEXACT) { #ifdef FE_INEXACT mode |= FE_INEXACT ; #else GSL_ERROR ("inexact exception not supported by <fenv.h>", GSL_EUNSUP); #endif } else { #ifdef FE_INEXACT mode &= ~ FE_INEXACT ; #else /* do nothing */ #endif } #if HAVE_DECL_FEENABLEEXCEPT feenableexcept (mode) ; #elif HAVE_DECL_FESETTRAPENABLE fesettrapenable (mode); #else GSL_ERROR ("unknown exception trap method", GSL_EUNSUP) #endif return GSL_SUCCESS ; }