void test_infinity (FloatT inf, FloatT max, const char *tname) { if (!std::numeric_limits<FloatT>::traps) { // infinity must be even greater than the maximum value rw_assert (inf > max, 0, __LINE__, "numeric_limits<%s>::infinity() > " "numeric_limits<%s>::max()", tname, tname); // multiplying infinity by anything other than 0.0 yields infinity rw_assert (inf == inf * inf, 0, __LINE__, "numeric_limits<%s>::infinity()", tname); } #ifdef _MSC_VER const int fpc = _fpclass (inf); rw_assert (_FPCLASS_PINF == fpc, 0, __LINE__, "_fpclass (numeric_limits<%s>::infinity()) == " "%d (_FPCLASS_PINF), got %d (%s)", tname, _FPCLASS_PINF, fpc, fpclass_name (fpc)); #elif defined (_RWSTD_OS_SUNOS) rw_assert (!finite (inf), 0, __LINE__, "finite (numeric_limits<%s>::infinity()) == 0, " "got non-zero", tname); const fpclass_t fpc = fpclass (inf); rw_assert (FP_PINF == fpclass (inf), 0, __LINE__, "fpclass (numeric_limits<%s>::infinity()) == %d (FP_PINF), " "got %d (%s)", tname, FP_PINF, fpc, fpclass_name (fpc)); #else # ifdef isinf rw_assert (isinf (inf), 0, __LINE__, "isinf (numeric_limits<%s>::infinity()) != 0, got 0", tname); # endif // isinf # ifdef fpclassify const int fpc = fpclassify (inf); rw_assert (FP_INFINITE == fpc, 0, __LINE__, "fpclassify(numeric_limits<%s>::infinity()) == " "%d (FP_INFINITE), got %d (%s)", tname, FP_INFINITE, fpc, fpclass_name (fpc)); # endif // fpclassify #endif }
int test_class(void) { int failures = 0; printf("Testing floating point classes... "); fflush(stdout); if(fpclass(one) != FP_PNORM) FAIL_TEST; if(fpclass(negone) != FP_NNORM) FAIL_TEST; if(fpclass(zero) != FP_PZERO) FAIL_TEST; if(fpclass(negzero) != FP_NZERO) FAIL_TEST; #if (defined(DENORM_BUG_SOLVED) && defined(__CYGWIN__)) || defined(__sun__) if(fpclass(DBL_MIN / three) != FP_PDENORM) FAIL_TEST; if(fpclass(-DBL_MIN / three) != FP_NDENORM) FAIL_TEST; #endif if(fpclass(DBL_MAX * two) != FP_PINF) FAIL_TEST; if(fpclass(DBL_MAX * negtwo) != FP_NINF) FAIL_TEST; if(fpclass(sqrt(negone)) != FP_QNAN) FAIL_TEST; if(failures == 0) { printf(" PASSED\n"); return 0; } else { printf(" %d failures\n", failures); return 1; } }
/* Returns -1 if value equals negative infinity, +1 if it is equal to positive infinity, or 0 if the number is not infinite. Note that on some systems, this method will always return 0 (i.e. false positives). */ int coin_isinf(double value) { #ifdef HAVE_ISINF return isinf(value); #elif defined(HAVE_FPCLASS) if (fpclass(value) == FP_NINF) { return -1; } if (fpclass(value) == FP_PINF) { return +1; } return 0; #elif defined(HAVE__FPCLASS) if (_fpclass(value) == _FPCLASS_NINF) { return -1; } if (_fpclass(value) == _FPCLASS_PINF) { return +1; } return 0; #else /* FIXME: it might be possible to investigate the fp bits and decide in a portable manner whether or not they represent an infinite. A groups.google.com search turned up inconclusive. 20030919 mortene. */ return 0; #endif }
int isinf(double d) { fpclass_t type = fpclass(d); switch (type) { case FP_NINF: case FP_PINF: return 1; default: break; } return 0; }
/* this function is only called if a NaN issue has been discovered */ static void handleInvalidValue(char *theDir, char *varName, int index, double value) { static char lastDir[1024], lastVar[1024]; char errMsg[128]; /* try to produce a useful error message regarding the kind of NaN */ #ifdef HAVE_FPCLASS { fpclass_t theClass = fpclass(value); switch (theClass) { case FP_SNAN: strcpy(errMsg,"signaling NaN"); break; case FP_QNAN: strcpy(errMsg,"quiet NaN"); break; case FP_NINF: strcpy(errMsg,"negative infinity"); break; case FP_PINF: strcpy(errMsg,"positive infinity"); break; case FP_NDENORM: strcpy(errMsg,"negative denormalized non-zero"); break; case FP_PDENORM: strcpy(errMsg,"positive denormalized non-zero"); break; case FP_NZERO: strcpy(errMsg,"negative zero"); break; case FP_PZERO: strcpy(errMsg,"positive zero"); break; case FP_NNORM: strcpy(errMsg,"negative normalized non-zero"); break; case FP_PNORM: strcpy(errMsg,"positive normalized non-zero"); break; } } #else strcpy(errMsg, "unkown NaN"); #endif if (!disableVerbose) { /* strip off leading slash for root dir */ if (strcmp(lastDir, theDir) || strcmp(lastVar, varName)) { if (!strcmp(theDir,"/")) printf(" simple array /%s...\n", varName); else printf(" simple array %s/%s...\n", theDir, varName); } printf(" ...has %s issue at index %d\n", errMsg, index); } else { /* early termination of we not using verbose mode */ printf(" found %s issue\n", errMsg); exit(-1); } /* keep a record of last dir and varname we used so we don't keep issuing the ` simple array ... statement ' */ strcpy(lastDir, theDir); strcpy(lastVar, varName); }
/* Returns 0 if the bitpattern of the \a value argument is not a valid floating point number, otherwise returns non-zero. Note that on some systems, this method will always return 0 (i.e. false positives). */ int coin_isnan(double value) { #ifdef HAVE_ISNAN return isnan(value); #elif defined(HAVE__ISNAN) return _isnan(value); #elif defined(HAVE_FPCLASS) if (fpclass(value) == FP_SNAN) { return 1; } if (fpclass(value) == FP_QNAN) { return 1; } return 0; #elif defined(HAVE__FPCLASS) if (_fpclass(value) == _FPCLASS_SNAN) { return 1; } if (_fpclass(value) == _FPCLASS_QNAN) { return 1; } return 0; #else /* FIXME: it might be possible to investigate the fp bits and decide in a portable manner whether or not they represent a NaN. A groups.google.com search turned up inconclusive. 20030919 mortene. */ return 0; #endif }
int finite(double num) { switch(fpclass(num)) { case FP_PDENORM: case FP_NDENORM: case FP_PNORM: case FP_NNORM: case FP_PZERO: case FP_NZERO: return 1; case FP_PINF: case FP_NINF: case FP_SNAN: case FP_QNAN: return 0; default: fprintf(stderr, "PANIC: fpclass returned invalid class\n"); abort(); } }
int dis_isinf (double num) { #ifdef HAVE_ISINF return isinf (num); #elif defined(HAVE_IEEEFP_H) fpclass_t klass; klass = fpclass (num); if (klass == FP_NINF) return -1; if (klass == FP_PINF) return 1; return 0; #elif defined(HAVE__FINITE) return _finite (num) ? 0 : 1; #else #error "Don't know how to implement isinf for this platform." #endif }
bool FPEnvironmentImpl::isInfiniteImpl(long double value) { int cls = fpclass(value); return cls == FP_PINF || cls == FP_NINF; }
I nanbeamchk(C *f,A af) { F *fp=(F *)af->p; I nans=0,infs=0,cl; if(Ft!=af->t)R 0; DO(af->n,cl=fpclass(fp[i]);if(cl==FP_NINF||cl==FP_PINF)++infs;if(cl==FP_SNAN |cl==FP_QNAN)++nans;);
void test_signaling_NaN (FloatT snan, FloatT snan2, const char *tname) { // NAN never compares equal to self or any other number rw_assert (!(snan == snan2), 0, __LINE__, "numeric_limits<%s>::signaling_NaN() != " "numeric_limits<%1$s>::signaling_NaN()", tname); const FloatT inf = std::numeric_limits<FloatT>::infinity (); rw_assert (!(snan == inf), 0, __LINE__, "numeric_limits<%s>::signaling_NaN() != " "numeric_limits<%1$s>::infinity()", tname); rw_assert (!(snan == -inf), 0, __LINE__, "numeric_limits<%s>::signaling_NaN() != " "-numeric_limits<%1$s>::infinity()", tname); #ifdef _MSC_VER rw_assert (0 != _isnan (snan), 0, __LINE__, "_isnan (numeric_limits<%s>::signaling_NaN()) != 0, got 0", tname); const int fpc = _fpclass (snan); rw_assert (_FPCLASS_SNAN == fpc, 0, __LINE__, "_fpclass(numeric_limits<%s>::signaling_NaN()) == " "%d (_FPCLASS_SNAN), got %d (%s)", tname, _FPCLASS_SNAN, fpc, fpclass_name (fpc)); #elif defined (_RWSTD_OS_SUNOS) rw_assert (!finite (snan), 0, __LINE__, "finite(numeric_limits<%s>::signaling_NaN()) == 0, " "got non-zero", tname); const fpclass_t fpc = fpclass (snan); rw_assert (FP_SNAN == fpc, 0, __LINE__, "fpclass(numeric_limits<%s>::signaling_NaN()) == %d " "(FP_SNAN), got %d (%s)", tname, FP_SNAN, fpc, fpclass_name (fpc)); #else # ifdef isnan rw_assert (0 != isnan (snan), 0, __LINE__, "isnan(numeric_limits<%s>::signaling_NaN()) != 0, got 0", tname); # endif // isnan # ifdef fpclassify const int fpc = fpclassify (snan); rw_assert (FP_NAN == fpc, 0, __LINE__, "fpclassify(numeric_limits<%s>::signaling_NaN()) == " "%d (FP_NAN), got %d (%s)", tname, FP_NAN, fpc, fpclass_name (fpc)); # endif // fpclassify #endif }
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)++; } } }