/* ** initialize the global tolerance ** should be called only once at the beginning of the program */ void T_initdefault() { static int called_before = 0; if (called_before) { Z_fatal("T_initdefault called more than once\n"); } /* ** if the default tolerance was set somewhere else ** don't set it here */ if (T_isnull(_T_gtol)) { T_defatol(_T_ADEF); T_defrtol(_T_RDEF); } called_before = 1; }
/* ** compare two F_floats using a tolerance */ static int _X_floatdiff(F_float p1,F_float p2,T_tol the_tol) { F_float diff, float_tmp; T_tol tol_tmp; /* ** check for null tolerance list */ if (T_isnull(the_tol)) { Z_fatal("_X_floatdiff called with a null tolerance"); } /* ** look for an easy answer. i.e -- check ** to see if any of the tolerances are of type T_IGNORE ** or if the numbers are too small to exceed an absolute ** tolerance. ** if so, return immediately */ for(tol_tmp=the_tol; !(T_isnull(tol_tmp)) ;tol_tmp=T_getnext(tol_tmp)) { if ((T_IGNORE == T_gettype(tol_tmp)) || /* ** take a look at the exponents before you bother ** with the mantissas */ ((T_ABSOLUTE == T_gettype(tol_tmp)) && !F_zerofloat(T_getfloat(tol_tmp)) && (F_getexp(p1) < F_getexp(T_getfloat(tol_tmp))-1) && (F_getexp(p2) < F_getexp(T_getfloat(tol_tmp))-1))) { return(0); } } /* ** ok, we're going to have to do some arithmetic, so ** first find the magnitude of the difference */ if (F_getsign(p1) != F_getsign(p2)) { diff = F_floatmagadd(p1,p2); } else { diff = F_floatsub(p1,p2); } /* ** now check to see if the difference exceeds any tolerance */ for(tol_tmp=the_tol; !(T_isnull(tol_tmp)) ;tol_tmp=T_getnext(tol_tmp)) { float_tmp = T_getfloat(tol_tmp); if (T_gettype(tol_tmp) == T_ABSOLUTE) { /* do nothing */ } else if (T_gettype(tol_tmp) == T_RELATIVE) { if (F_floatcmp(p1,p2) > 0) { float_tmp = F_floatmul(p1, float_tmp); } else { float_tmp = F_floatmul(p2, float_tmp); } } else { Z_fatal("bad value for type of tolerance in floatdiff"); } /* ** if we pass this tolerance, then we're done */ if (F_floatcmp(diff,float_tmp) <= 0) { return(0); } } /* ** all of the tolerances were exceeded */ return(1); }