예제 #1
0
int test_settings(void) {
  int failures = 0;
  fp_except mask_orig;

  printf("Testing settings on the chip... ");
  fflush(stdout);

  fpsetround(FP_RM);
  if(fpgetround() != FP_RM) FAIL_TEST;
  fpsetround(FP_RP);
  if(fpgetround() != FP_RP) FAIL_TEST;
  fpsetround(FP_RZ);
  if(fpgetround() != FP_RZ) FAIL_TEST;
  fpsetround(FP_RN);
  if(fpgetround() != FP_RN) FAIL_TEST;
 
  fpsetsticky(FP_X_INV | FP_X_DZ | FP_X_IMP);
  if(fpgetsticky() != (FP_X_INV | FP_X_DZ | FP_X_IMP)) FAIL_TEST;
  fpsetsticky(FP_X_OFL | FP_X_IMP);
  if(fpgetsticky() != (FP_X_OFL | FP_X_IMP)) FAIL_TEST;
  fpsetsticky(FP_X_UFL | FP_X_DZ);
  if(fpgetsticky() != (FP_X_UFL | FP_X_DZ)) FAIL_TEST;
  fpsetsticky(0);
  if(fpgetsticky() != 0) FAIL_TEST;

  mask_orig = fpsetmask(FP_X_INV | FP_X_DZ);
  if(fpgetmask() != (FP_X_INV | FP_X_DZ)) FAIL_TEST;
  fpsetmask(FP_X_OFL | FP_X_IMP);
  if(fpgetmask() != (FP_X_OFL | FP_X_IMP)) FAIL_TEST;
  fpsetmask(FP_X_UFL | FP_X_DZ | FP_X_INV);
  if(fpgetmask() != (FP_X_UFL | FP_X_DZ | FP_X_INV)) FAIL_TEST;
  fpsetmask(mask_orig);
  if(fpgetmask() != mask_orig) FAIL_TEST;

#ifdef __CYGWIN__
  fpsetprecision(FP_PC_SGL);
  if(fpgetprecision() != FP_PC_SGL) FAIL_TEST;
  fpsetprecision(FP_PC_DBL);
  if(fpgetprecision() != FP_PC_DBL) FAIL_TEST;
  fpsetprecision(FP_PC_EXT);
  if(fpgetprecision() != FP_PC_EXT) FAIL_TEST;
#endif

  if(failures == 0) {
    printf(" PASSED\n");
    return 0;
  }
  else {
    printf(" %d failures\n", failures);
    return 1;
  }
}
예제 #2
0
파일: fenv.c 프로젝트: ajinkya93/netbsd-src
/*
 * The feraiseexcept() function shall attempt to raise the supported
 * floating-point exceptions represented by the argument excepts. The order
 * in which these floating-point exceptions are raised is unspecified. 
 */
int
feraiseexcept(int excepts)
{
#ifndef lint
	_DIAGASSERT((except & ~FE_ALL_EXCEPT) == 0);
#endif
#ifdef __SOFTFP__
	excepts &= fpgetsticky();

	if (excepts) {
		siginfo_t info;
		memset(&info, 0, sizeof info);
		info.si_signo = SIGFPE;
		info.si_pid = getpid();
		info.si_uid = geteuid();
		if (excepts & FE_UNDERFLOW)
			info.si_code = FPE_FLTUND;
		else if (excepts & FE_OVERFLOW)
			info.si_code = FPE_FLTOVF;
		else if (excepts & FE_DIVBYZERO)
			info.si_code = FPE_FLTDIV;
		else if (excepts & FE_INVALID)
			info.si_code = FPE_FLTINV;
		else if (excepts & FE_INEXACT)
			info.si_code = FPE_FLTRES;
		sigqueueinfo(getpid(), &info);
	}
#else
	int fpscr = armreg_fpscr_read();
	fpscr = (fpscr & ~VFP_FPSCR_ESUM) | __SHIFTIN(excepts, VFP_FPSCR_ESUM);
	armreg_fpscr_write(fpscr);
#endif
	return 0;
}
예제 #3
0
파일: fenv.c 프로젝트: ajinkya93/netbsd-src
/*
 * The fetestexcept() function shall determine which of a specified subset of
 * the floating-point exception flags are currently set. The excepts argument
 * specifies the floating-point status flags to be queried.
 */
int
fetestexcept(int excepts)
{
	_DIAGASSERT((except & ~FE_ALL_EXCEPT) == 0);
#ifdef __SOFTFP__
	return fpgetsticky() & excepts;
#else
	return __SHIFTOUT(armreg_fpscr_read(), VFP_FPSCR_CSUM) & excepts;
#endif
}
예제 #4
0
static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args)
{
#ifdef __FreeBSD__
    fpresetsticky(fpgetsticky());
    fpsetmask(0);
#else
    fputs("Operation not implemented\n", stderr);
#endif
    Py_RETURN_NONE;
}
예제 #5
0
파일: float.c 프로젝트: DavidGriffith/tme
/* update the current exceptions: */
static void
_tme_float_exceptions_update(int at_least_one)
{
  int exceptions_new;
#ifdef HAVE_FPGETSTICKY
  int sticky;
#endif /* HAVE_FPGETSTICKY */

  /* start with no new exceptions: */
  exceptions_new = 0;

  /* get the exception status: */
#ifdef HAVE_FPGETSTICKY
  sticky = fpgetsticky();
#define TME_FP_X_MAP(fp_x, float_x) if (sticky & (fp_x)) exceptions_new |= (float_x)
#ifdef FP_X_INV
  TME_FP_X_MAP(FP_X_INV, TME_FLOAT_EXCEPTION_INVALID);
#endif
#ifdef FP_X_DNML
  TME_FP_X_MAP(FP_X_DNML, TME_FLOAT_EXCEPTION_DENORMAL);
#endif
#ifdef FP_X_DZ
  TME_FP_X_MAP(FP_X_DZ, TME_FLOAT_EXCEPTION_DIVBYZERO);
#endif
#ifdef FP_X_OFL
  TME_FP_X_MAP(FP_X_OFL, TME_FLOAT_EXCEPTION_OVERFLOW);
#endif
#ifdef FP_X_UFL
  TME_FP_X_MAP(FP_X_UFL, TME_FLOAT_EXCEPTION_UNDERFLOW);
#endif
#ifdef FP_X_IMP
  TME_FP_X_MAP(FP_X_IMP, TME_FLOAT_EXCEPTION_INEXACT);
#endif
#ifdef FP_X_IOV
  TME_FP_X_MAP(FP_X_IOV, TME_FLOAT_EXCEPTION_OVERFLOW_INT);
#endif
#undef TME_FP_X_MAP
#endif /* HAVE_FPGETSTICKY */

  /* if we have no new exceptions, but we should have at least one,
     add in the generic exception: */
  if (exceptions_new == 0
      && at_least_one) {
    exceptions_new |= TME_FLOAT_EXCEPTION_GENERIC;
  }

  /* accumulate the new exceptions into the current exceptions: */
  _tme_float_exceptions |= exceptions_new;
  
  /* clear the exception status: */
#ifdef HAVE_FPSETSTICKY
  fpsetsticky(0);
#endif /* HAVE_FPSETSTICKY */
}
예제 #6
0
파일: fenv.c 프로젝트: ajinkya93/netbsd-src
/*
 * The fegetexceptflag() function shall attempt to store an
 * implementation-defined representation of the states of the floating-point
 * status flags indicated by the argument excepts in the object pointed to by
 * the argument flagp.
 */
int
fegetexceptflag(fexcept_t *flagp, int excepts)
{
	_DIAGASSERT((except & ~FE_ALL_EXCEPT) == 0);
#ifdef __SOFTFP__
	*flagp = fpgetsticky() & excepts;
#else
	*flagp = __SHIFTOUT(armreg_fpscr_read(), VFP_FPSCR_CSUM) & excepts;
#endif
	return 0;
}
예제 #7
0
파일: fenv.c 프로젝트: ajinkya93/netbsd-src
/*
 * The fegetenv() function shall attempt to store the current floating-point
 * environment in the object pointed to by envp.
 */
int
fegetenv(fenv_t *envp)
{
#ifdef __SOFTFP__
	*envp = __SHIFTIN(fpgetround(), VFP_FPSCR_RMODE)
	    | __SHIFTIN(fpgetmask(), VFP_FPSCR_ESUM)
	    | __SHIFTIN(fpgetsticky(), VFP_FPSCR_CSUM);
#else
	*envp = armreg_fpscr_read();
#endif
	return 0;
}
예제 #8
0
파일: fenv.c 프로젝트: ajinkya93/netbsd-src
/*
 * The feclearexcept() function shall attempt to clear the supported
 * floating-point exceptions represented by excepts.
 */
int
feclearexcept(int excepts)
{
#ifndef lint
	_DIAGASSERT((except & ~FE_ALL_EXCEPT) == 0);
#endif
#ifdef __SOFTFP__
	fpsetsticky(fpgetsticky() & ~excepts);
	return 0;
#else
	int tmp = armreg_fpscr_read() & ~__SHIFTIN(excepts, VFP_FPSCR_CSUM);
	armreg_fpscr_write(tmp);
	return 0;
#endif
}
예제 #9
0
파일: fenv.c 프로젝트: ajinkya93/netbsd-src
/*
 * The feholdexcept() function shall save the current floating-point
 * environment in the object pointed to by envp, clear the floating-point
 * status flags, and then install a non-stop (continue on floating-point
 * exceptions) mode, if available, for all floating-point exceptions.
 */
int
feholdexcept(fenv_t *envp)
{
#ifdef __SOFTFP__
	*envp = __SHIFTIN(fpgetround(), VFP_FPSCR_RMODE)
	    | __SHIFTIN(fpgetmask(), VFP_FPSCR_ESUM)
	    | __SHIFTIN(fpgetsticky(), VFP_FPSCR_CSUM);
	fpsetmask(0);
	fpsetsticky(0);
#else
	*envp = armreg_fpscr_read();
	armreg_fpscr_write((*envp) & ~(VFP_FPSCR_ESUM|VFP_FPSCR_CSUM));
#endif
	return 0;
}
예제 #10
0
파일: fenv.c 프로젝트: ajinkya93/netbsd-src
/*
 * The fesetexceptflag() function shall attempt to set the floating-point
 * status flags indicated by the argument excepts to the states stored in the
 * object pointed to by flagp. The value pointed to by flagp shall have been
 * set by a previous call to fegetexceptflag() whose second argument
 * represented at least those floating-point exceptions represented by the
 * argument excepts. This function does not raise floating-point exceptions,
 * but only sets the state of the flags.
 */
int
fesetexceptflag(const fexcept_t *flagp, int excepts)
{
#ifndef lint
	_DIAGASSERT((except & ~FE_ALL_EXCEPT) == 0);
#endif
#ifdef __SOFTFP__
	fpsetsticky((fpgetsticky() & ~excepts) | (excepts & *flagp));
#else
	int fpscr = armreg_fpscr_read();
	fpscr &= ~__SHIFTIN(excepts, VFP_FPSCR_CSUM);
	fpscr |= __SHIFTIN((*flagp & excepts), VFP_FPSCR_CSUM);
	armreg_fpscr_write(fpscr);
#endif
	return 0;
}
예제 #11
0
static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args)
{
#ifdef __FreeBSD__
    fpresetsticky(fpgetsticky());
    fpsetmask(0);
#elif defined(__VMS)
	IEEE clrmsk;
	 clrmsk.ieee$q_flags =
		IEEE$M_TRAP_ENABLE_UNF |  IEEE$M_TRAP_ENABLE_INE |
		IEEE$M_MAP_UMZ | IEEE$M_TRAP_ENABLE_INV |
		IEEE$M_TRAP_ENABLE_DZE | IEEE$M_TRAP_ENABLE_OVF |
		IEEE$M_INHERIT;
	sys$ieee_set_fp_control(&clrmsk, 0, 0);
#else
    fputs("Operation not implemented\n", stderr);
#endif
    Py_INCREF(Py_None);
    return Py_None;
}
예제 #12
0
파일: fenv.c 프로젝트: ajinkya93/netbsd-src
/*
 * The feupdateenv() function shall attempt to save the currently raised
 * floating-point exceptions in its automatic storage, attempt to install the
 * floating-point environment represented by the object pointed to by envp,
 * and then attempt to raise the saved floating-point exceptions. 
 */
int
feupdateenv(const fenv_t *envp)
{
#ifndef lint
	_DIAGASSERT(envp != NULL);
#endif
#ifdef __SOFTFP__
	(void)fpsetround(__SHIFTIN(*envp, VFP_FPSCR_RMODE));
	(void)fpsetmask(fpgetmask() | __SHIFTOUT(*envp, VFP_FPSCR_ESUM));
	(void)fpsetsticky(fpgetsticky() | __SHIFTOUT(*envp, VFP_FPSCR_CSUM));
#else
	int fpscr = armreg_fpscr_read() & ~(VFP_FPSCR_ESUM|VFP_FPSCR_CSUM);
	fpscr |= *envp;
	armreg_fpscr_write(fpscr);
#endif

	/* Success */
	return 0;
}
예제 #13
0
int test_sticky(void) {
  double ans;
  int failures = 0;

  printf("Testing sticky bits... ");
  fflush(stdout);

  fpsetsticky(0);
  ans = two / three;
  if((fpgetsticky() & FP_X_IMP) != FP_X_IMP) FAIL_TEST;

  fpsetsticky(0);
  ans = DBL_MIN / three;
  if((fpgetsticky() & FP_X_UFL) != FP_X_UFL) FAIL_TEST;
#ifdef __CYGWIN__
  ans = ans / three;
  if((fpgetsticky() & FP_X_DNML) != FP_X_DNML) FAIL_TEST;
#endif

  fpsetsticky(0);
  ans = DBL_MAX * three;
  if((fpgetsticky() & FP_X_OFL) != FP_X_OFL) FAIL_TEST;

  fpsetsticky(0);
  ans = one / zero;
  if((fpgetsticky() & FP_X_DZ) != FP_X_DZ) FAIL_TEST;

  fpsetsticky(0);
  ans = sqrt(negone);
  if((fpgetsticky() & FP_X_INV) != FP_X_INV) FAIL_TEST;

  fpsetsticky(0);
 
  if(failures == 0) {
    printf(" PASSED\n");
    return 0;
  }
  else {
    printf(" %d failures\n", failures);
    return 1;
  }
}
예제 #14
0
static void fpe_reset(Sigfunc *handler)
{
    /* Reset the exception handling machinery, and reset the signal
     * handler for SIGFPE to the given handler.
     */

/*-- SunOS and Solaris ----------------------------------------------------*/
#if defined(sun)
    /* References: ieee_handler, ieee_sun, ieee_functions, and ieee_flags
       man pages (SunOS or Solaris)
       cc -c -I/usr/local/python/include fpectlmodule.c
       ld -G -o fpectlmodule.so -L/opt/SUNWspro/lib fpectlmodule.o -lsunmath -lm
     */
#include <math.h>
#ifndef _SUNMATH_H
    extern void nonstandard_arithmetic(void);
    extern int ieee_flags(const char*, const char*, const char*, char **);
    extern long ieee_handler(const char*, const char*, sigfpe_handler_type);
#endif

    char *mode="exception", *in="all", *out;
    (void) nonstandard_arithmetic();
    (void) ieee_flags("clearall",mode,in,&out);
    (void) ieee_handler("set","common",(sigfpe_handler_type)handler);
    PyOS_setsig(SIGFPE, handler);

/*-- HPUX -----------------------------------------------------------------*/
#elif defined(__hppa) || defined(hppa)
    /* References:   fpsetmask man page */
    /* cc -Aa +z -c -I/usr/local/python/include fpectlmodule.c */
    /* ld -b -o fpectlmodule.sl fpectlmodule.o -lm */
#include <math.h>
    fpsetdefaults();
    PyOS_setsig(SIGFPE, handler);

/*-- IBM AIX --------------------------------------------------------------*/
#elif defined(__AIX) || defined(_AIX)
    /* References:   fp_trap, fp_enable man pages */
#include <fptrap.h>
    fp_trap(FP_TRAP_SYNC);
    fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW);
    PyOS_setsig(SIGFPE, handler);

/*-- DEC ALPHA LINUX ------------------------------------------------------*/
#elif defined(__alpha) && defined(linux)
#include <asm/fpu.h>
    unsigned long fp_control =
    IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF;
    ieee_set_fp_control(fp_control);
    PyOS_setsig(SIGFPE, handler);

/*-- Cray Unicos ----------------------------------------------------------*/
#elif defined(cray)
    /* UNICOS delivers SIGFPE by default, but no matherr */
#ifdef HAS_LIBMSET
    libmset(-1);
#endif
    PyOS_setsig(SIGFPE, handler);

/*-- FreeBSD ----------------------------------------------------------------*/
#elif defined(__FreeBSD__)
    fpresetsticky(fpgetsticky());
    fpsetmask(FP_X_INV | FP_X_DZ | FP_X_OFL);
    PyOS_setsig(SIGFPE, handler);

/*-- Linux ----------------------------------------------------------------*/
#elif defined(linux)
#ifdef __GLIBC__
#include <fpu_control.h>
#else
#include <i386/fpu_control.h>
#endif
#ifdef _FPU_SETCW
    {
        fpu_control_t cw = 0x1372;
        _FPU_SETCW(cw);
    }
#else
    __setfpucw(0x1372);
#endif
    PyOS_setsig(SIGFPE, handler);

/*-- Microsoft Windows, NT ------------------------------------------------*/
#elif defined(_MSC_VER)
    /* Reference: Visual C++ Books Online 4.2,
       Run-Time Library Reference, _control87, _controlfp */
#include <float.h>
    unsigned int cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW;
    (void)_controlfp(0, cw);
    PyOS_setsig(SIGFPE, handler);

/*-- Give Up --------------------------------------------------------------*/
#else
    fputs("Operation not implemented\n", stderr);
#endif

}
예제 #15
0
static void fpe_reset(Sigfunc *handler)
{
    /* Reset the exception handling machinery, and reset the signal
     * handler for SIGFPE to the given handler.
     */

/*-- IRIX -----------------------------------------------------------------*/
#if defined(sgi)
    /* See man page on handle_sigfpes -- must link with -lfpe
     * My usage doesn't follow the man page exactly.  Maybe somebody
     * else can explain handle_sigfpes to me....
     * cc -c -I/usr/local/python/include fpectlmodule.c
     * ld -shared -o fpectlmodule.so fpectlmodule.o -lfpe 
     */
#include <sigfpe.h>
    typedef void user_routine (unsigned[5], int[2]);
    typedef void abort_routine (unsigned long);
    handle_sigfpes(_OFF, 0,
		 (user_routine *)0,
		 _TURN_OFF_HANDLER_ON_ERROR,
		 NULL);
    handle_sigfpes(_ON, _EN_OVERFL | _EN_DIVZERO | _EN_INVALID,
		 (user_routine *)0,
		 _ABORT_ON_ERROR,
		 NULL);
    PyOS_setsig(SIGFPE, handler);

/*-- SunOS and Solaris ----------------------------------------------------*/
#elif defined(sun)
    /* References: ieee_handler, ieee_sun, ieee_functions, and ieee_flags
       man pages (SunOS or Solaris)
       cc -c -I/usr/local/python/include fpectlmodule.c
       ld -G -o fpectlmodule.so -L/opt/SUNWspro/lib fpectlmodule.o -lsunmath -lm
     */
#include <math.h>
#ifndef _SUNMATH_H
    extern void nonstandard_arithmetic(void);
    extern int ieee_flags(const char*, const char*, const char*, char **);
    extern long ieee_handler(const char*, const char*, sigfpe_handler_type);
#endif

    char *mode="exception", *in="all", *out;
    (void) nonstandard_arithmetic();
    (void) ieee_flags("clearall",mode,in,&out);
    (void) ieee_handler("set","common",(sigfpe_handler_type)handler);
    PyOS_setsig(SIGFPE, handler);

/*-- HPUX -----------------------------------------------------------------*/
#elif defined(__hppa) || defined(hppa)
    /* References:   fpsetmask man page */
    /* cc -Aa +z -c -I/usr/local/python/include fpectlmodule.c */
    /* ld -b -o fpectlmodule.sl fpectlmodule.o -lm */
#include <math.h>
    fpsetdefaults();
    PyOS_setsig(SIGFPE, handler);

/*-- IBM AIX --------------------------------------------------------------*/
#elif defined(__AIX) || defined(_AIX)
    /* References:   fp_trap, fp_enable man pages */
#include <fptrap.h>
    fp_trap(FP_TRAP_SYNC);
    fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW);
    PyOS_setsig(SIGFPE, handler);

/*-- DEC ALPHA OSF --------------------------------------------------------*/
#elif defined(__alpha) && defined(__osf__)
    /* References:   exception_intro, ieee man pages */
    /* cc -c -I/usr/local/python/include fpectlmodule.c */
    /* ld -shared -o fpectlmodule.so fpectlmodule.o */
#include <machine/fpu.h>
    unsigned long fp_control =
    IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF;
    ieee_set_fp_control(fp_control);
    PyOS_setsig(SIGFPE, handler);

/*-- DEC ALPHA LINUX ------------------------------------------------------*/
#elif defined(__alpha) && defined(linux)
#include <asm/fpu.h>
    unsigned long fp_control =
    IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF;
    ieee_set_fp_control(fp_control);
    PyOS_setsig(SIGFPE, handler);

/*-- DEC ALPHA VMS --------------------------------------------------------*/
#elif defined(__ALPHA) && defined(__VMS)
	IEEE clrmsk;
	IEEE setmsk;
	clrmsk.ieee$q_flags =
		IEEE$M_TRAP_ENABLE_UNF |  IEEE$M_TRAP_ENABLE_INE |
		 IEEE$M_MAP_UMZ;
	setmsk.ieee$q_flags =
		IEEE$M_TRAP_ENABLE_INV | IEEE$M_TRAP_ENABLE_DZE |
		IEEE$M_TRAP_ENABLE_OVF;
	sys$ieee_set_fp_control(&clrmsk, &setmsk, 0);
	PyOS_setsig(SIGFPE, handler);

/*-- HP IA64 VMS --------------------------------------------------------*/
#elif defined(__ia64) && defined(__VMS)
    PyOS_setsig(SIGFPE, handler);

/*-- Cray Unicos ----------------------------------------------------------*/
#elif defined(cray)
    /* UNICOS delivers SIGFPE by default, but no matherr */
#ifdef HAS_LIBMSET
    libmset(-1);
#endif
    PyOS_setsig(SIGFPE, handler);

/*-- FreeBSD ----------------------------------------------------------------*/
#elif defined(__FreeBSD__)
    fpresetsticky(fpgetsticky());
    fpsetmask(FP_X_INV | FP_X_DZ | FP_X_OFL);
    PyOS_setsig(SIGFPE, handler);

/*-- Linux ----------------------------------------------------------------*/
#elif defined(linux)
#ifdef __GLIBC__
#include <fpu_control.h>
#else
#include <i386/fpu_control.h>
#endif
#ifdef _FPU_SETCW
    {
        fpu_control_t cw = 0x1372;
        _FPU_SETCW(cw);
    }
#else
    __setfpucw(0x1372);
#endif
    PyOS_setsig(SIGFPE, handler);

/*-- Microsoft Windows, NT ------------------------------------------------*/
#elif defined(_MSC_VER)
    /* Reference: Visual C++ Books Online 4.2,
       Run-Time Library Reference, _control87, _controlfp */
#include <float.h>
    unsigned int cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW;
    (void)_controlfp(0, cw);
    PyOS_setsig(SIGFPE, handler);

/*-- Give Up --------------------------------------------------------------*/
#else
    fputs("Operation not implemented\n", stderr);
#endif

}
예제 #16
0
void op(double num1, double num2, OPERATOR op, int dir, FILE *fp,
	int *nopdiffs, int *nansdiffs, int *nxdiffs, int *nclsdiffs) {
  double ans1;
  char snum1[(DBL2CHR * 2) + 1], snum2[(DBL2CHR * 2) + 1],
    sans1[(DBL2CHR * 2) + 1];
  fp_except x;
  fp_pctl pc;

  pc = fpsetprecision(FP_PC_DBL);
  fpsetsticky(0);
  if(dir >= 0 && dir <= 3) {
    fpsetround(fpdir[dir]);
  }
  else {
    abort();
  }
  switch(op) {
  case PLUS:
    ans1 = num1 + num2;
    break;
  case MINUS:
    ans1 = num1 - num2;
    break;
  case DIVIDE:
    ans1 = num1 / num2;
    break;
  case MULTIPLY:
    ans1 = num1 * num2;
    break;
  default:
    abort();
  }
  x = fpgetsticky();
  fpsetprecision(pc);
  print(num1, snum1);
  print(num2, snum2);
  print(ans1, sans1);
  if(fp == NULL) {
    printf("%s %s %s %s = %s [ %s ]",
	   snum1, operators[op], rnddir[dir], snum2, sans1,
	   fpcls[fpclass(ans1)]);
    if(x & FP_X_INV) printf(" INV");
    if(x & FP_X_DZ) printf(" DZ");
    if(x & FP_X_OFL) printf(" OFL");
    if(x & FP_X_UFL) printf(" UFL");
    if(x & FP_X_IMP) printf(" IMP");
#ifdef FP_X_DNML
    if(x & FP_X_DNML) printf(" DNML");
#endif
    printf(" end\n");
  }
  else {
    char fp_op[MAXOPLEN], fp_rnd[MAXRNDLEN];
    char fp_num1[(DBL2CHR * 2) + 1], fp_num2[(DBL2CHR * 2) + 1],
      fp_ans1[(DBL2CHR * 2) + 1];
    char fp_cls[MAXFPCLS];
    char xbuf[MAXXLEN];
    int inv = 0, dz = 0, ofl = 0, ufl = 0, imp = 0, dnml = 0;
    int thisopdiff = 0, thisansdiff = 0, thisxdiff = 0, thisclsdiff = 0;
    fpclass_t thiscls;

    if(fscanf(fp, "%s %s %s %s = %s [ %s ]",
	      fp_num1, fp_op, fp_rnd, fp_num2, fp_ans1, fp_cls) != 6) {
      fprintf(stderr, "Problem reading comparison file\n");
      abort();
    }
    
    if(strcmp(operators[op], fp_op) != 0) {
      fprintf(stderr, "Operator mismatch in comparison file "
	      "(expecting %s found %s)\n", operators[op], fp_op);
      abort();
    }
    if(strcmp(rnddir[dir], fp_rnd) != 0) {
      fprintf(stderr, "Rounding direction mismatch in comparison file "
	      "(expecting %s found %s)\n", rnddir[dir], fp_rnd);
      abort();
    }

    if(strcmp(fp_num1, snum1) != 0) {
      thisopdiff = 1;
    }
    if(strcmp(fp_num2, snum2) != 0) {
      thisopdiff = 1;
    }
    if(strcmp(fp_ans1, sans1) != 0) {
      thisansdiff = 1;
    }
    thiscls = fpclass(ans1);
    if(strcmp(fp_cls, fpcls[thiscls]) != 0) {
      thisclsdiff = 1;
    }
    do {
      if(fscanf(fp, "%s", xbuf) != 1) {
	fprintf(stderr, "Problem reading comparison file");
	abort();
      }
      if(strcmp(xbuf, "INV") == 0) inv = FP_X_INV;
      else if(strcmp(xbuf, "DZ") == 0) dz = FP_X_DZ;
      else if(strcmp(xbuf, "UFL") == 0) ufl = FP_X_UFL;
      else if(strcmp(xbuf, "OFL") == 0) ofl = FP_X_OFL;
      else if(strcmp(xbuf, "IMP") == 0) imp = FP_X_IMP;
#ifdef FP_X_DNML
      else if(strcmp(xbuf, "DNML") == 0) dnml = FP_X_DNML;
#else
      else if(strcmp(xbuf, "DNML") == 0) dnml = -1;
#endif
      else if(strcmp(xbuf, "end") != 0) {
	fprintf(stderr, "Problem reading comparison file");
	abort();
      }
    } while(strcmp(xbuf, "end") != 0);

    if(inv != (x & FP_X_INV)) thisxdiff = 1;
    if(dz != (x & FP_X_DZ)) thisxdiff = 1;
    if(ufl != (x & FP_X_UFL)) thisxdiff = 1;
    if(ofl != (x & FP_X_OFL)) thisxdiff = 1;
    if(imp != (x & FP_X_IMP)) thisxdiff = 1;
#ifdef FP_X_DNML
    if(dnml != (x & FP_X_DNML)) thisxdiff = 1;
#else
    if(dnml == -1) thisxdiff = 1;
#endif
    
    if(thisansdiff || thisxdiff || thisclsdiff) {
      printf("In calculation %g %s %g = %g (rounding %s):\n",
	     num1, operators[op], num2, ans1, rnddir[dir]);
      if(thisansdiff && thisopdiff) {
	printf("\tOperators differ leading to different answer:\n");
	printf("\t\tFILE: op1=%s op2=%s ans=%s (%g)\n"
	       "\t\tHERE: op1=%s op2=%s ans=%s\n",
	       fp_num1, fp_num2, fp_ans1, input(fp_ans1), snum1, snum2, sans1);
      }
      else if(thisansdiff) {
	printf("\tDifferent answer:\n\t\tFILE: ans=%s (%g)\n"
	       "\t\tHERE: ans=%s\n",
	       fp_ans1, input(fp_ans1), sans1);
      }
      else if(thisclsdiff) {
	printf("\tDifferent class:\n"
	       "\t\tFILE: %s\n\t\tHERE: %s\n",
	       fp_cls, fpcls[thiscls]);
      }
      if(thisxdiff) {
	printf("\tDifferent exceptions raised:\n"
	       "\t\tFILE: %s %s %s %s %s %s\n"
	       "\t\tHERE: %s %s %s %s %s %s\n",
	       inv ? "I" : "-", dz ? "Z" : "-", ufl ? "U" : "-",
	       ofl ? "O" : "-", imp ? "P" : "-", dnml ? "D" : "-",
	       (x & FP_X_INV) ? "I" : "-", (x & FP_X_DZ) ? "Z" : "-",
	       (x & FP_X_UFL) ? "U" : "-", (x & FP_X_OFL) ? "O" : "-",
	       (x & FP_X_IMP) ? "P" : "-",
#ifdef FP_X_DNML
	       (x & FP_X_DNML) ? "D" : "-"
#else
	       "-"
#endif
	       );
      }
    }
    if(thisopdiff) (*nopdiffs)++;
    else if(thisansdiff) (*nansdiffs)++;
    else {
      if(thisxdiff) (*nxdiffs)++;
      if(thisclsdiff) (*nclsdiffs)++;
    }
  }
}
예제 #17
0
bool FPEnvironmentImpl::isFlagImpl(FlagImpl flag)
{
	return (fpgetsticky() & flag) != 0;
}
예제 #18
0
int
main(int argc, char *argv[])
{
	struct sigaction sa;
	volatile double x;

	if (argc != 2) {
		fprintf(stderr, "usage: %s condition\n", argv[0]);
		exit(1);
	}

	/*
	 * check to make sure that all exceptions are masked and 
	 * that the accumulated exception status is clear.
 	 */
	assert(fpgetmask() == 0);
	assert(fpgetsticky() == 0);

	memset(&sa, 0, sizeof(sa));
	sa.sa_sigaction = sigfpe;
	sa.sa_flags = SA_SIGINFO;
	sigaction(SIGFPE, &sa, NULL);
	signal_status = 1;

	if (strcmp(argv[1], "fltdiv") == 0) {
		/* trip divide by zero */
		x = one / zero;
		assert(fpgetsticky() & FP_X_DZ);
		fpsetsticky(0);

		/* and now unmask to get a signal */
		signal_status = 0;
		fpsetmask(FP_X_DZ);
		x = one / zero;
	} else if (strcmp(argv[1], "fltinv") == 0) {
		/* trip invalid operation */
		x = zero / zero;
		assert(fpgetsticky() & FP_X_INV);
		fpsetsticky(0);

		/* and now unmask to get a signal */
		signal_status = 0;
		fpsetmask(FP_X_INV);
		x = zero / zero;
	} else if (strcmp(argv[1], "fltovf") == 0) {
		/* trip overflow */
		x = huge * huge;
		assert(fpgetsticky() & FP_X_OFL);
		fpsetsticky(0);

		/* and now unmask to get a signal */
		signal_status = 0;
		fpsetmask(FP_X_OFL);
		x = huge * huge;
	} else if (strcmp(argv[1], "fltund") == 0) {
		/* trip underflow */
		x = tiny * tiny;
		assert(fpgetsticky() & FP_X_UFL);
		fpsetsticky(0);

		/* and now unmask to get a signal */
		signal_status = 0;
		fpsetmask(FP_X_UFL);
		x = tiny * tiny;
	} else {
		errx(1, "unrecognized condition %s", argv[1]);
	}

	/*
	 * attempt to trigger the exception on machines where
	 * floating-point exceptions are deferred.
	 */
	x = one * one;

	errx(1, "signal wasn't caught");
}