ulpdown(U *d) #endif { double u; ULong *L = d->L; u = ulp(d); if (!(L[_1] | (L[_0] & 0xfffff)) && (L[_0] & 0x7ff00000) > 0x00100000) u *= 0.5; return u; }
int test() { int Error(0); glm::uint ulp(0); float diff(0.0f); for(float f = 0.001f; f < 10.f; f *= 1.001f) { glm::lowp_fvec1 lowp_v = glm::inversesqrt(glm::lowp_fvec1(f)); float defaultp_v = glm::inversesqrt(f); ulp = glm::max(glm::float_distance(lowp_v.x, defaultp_v), ulp); diff = glm::abs(lowp_v.x - defaultp_v); } return Error; }
int main(int argc, char** argv) { SETUP(); int iter, repet; iter = 1 << 15; repet = 100; if (argc > 1) iter = atoi(argv[1]); if (argc > 2) repet = atoi(argv[2]); printf("pts,repet,avg,se\n"); for (j = 2; j < iter; j *= 2) { r1 = r2 = 0; mcount = -1; for (k = 0; k < repet; k++) { SAMPLE(j); TEST(im, j); SAVE(j); TEST(if, j); total = 0; for (i = 0; i < j; i++) { if (1 / correct[i] != 0 && correct[i] == correct[i]) { unsigned long long int error = ulp(out[i], correct[i]); total += log(error + 1.0) / log(2); } } r1old = r1; r1 += (total / count - r1) / (k + 1); r2 += (total / count - r1old) * (total / count - r1); if (mcount == -1 || count < mcount) mcount = count; free(rands); free(out); free(correct); } printf("%i,%i,%g,%g\n", mcount, repet, r1, sqrt(r2 / (repet - 1.5)) / sqrt(repet)); } }
void check2 (double x, int px, double y, int py, int pz, mp_rnd_t rnd_mode) { mpfr_t xx, yy, zz; double z,z2; int u; mpfr_init2(xx,px); mpfr_init2(yy,py); mpfr_init2(zz,pz); mpfr_set_d(xx, x, rnd_mode); mpfr_set_d(yy, y, rnd_mode); mpfr_add(zz, xx, yy, rnd_mode); mpfr_set_machine_rnd_mode(rnd_mode); z = x+y; z2=mpfr_get_d1 (zz); u=ulp(z,z2); /* one ulp difference is possible due to composed rounding */ if (px>=53 && py>=53 && pz>=53 && ABS(u)>1) { printf("x=%1.20e,%d y=%1.20e,%d pz=%d,rnd=%s\n", x,px,y,py,pz,mpfr_print_rnd_mode(rnd_mode)); printf("got %1.20e\n",z2); printf("result should be %1.20e (diff=%d ulp)\n",z,u); mpfr_set_d(zz, z, rnd_mode); printf("i.e."); mpfr_print_binary(zz); putchar('\n'); exit(1); } mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz); }
#endif #ifdef Avoid_Underflow /*{*/ static double sulp #ifdef KR_headers (x, scale) U *x; int scale; #else (U *x, int scale) #endif { U u; double rv; int i; rv = ulp(x); if (!scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0) return rv; /* Is there an example where i <= 0 ? */ word0(&u) = Exp_1 + (i << Exp_shift); word1(&u) = 0; return rv * u.d; } #endif /*}*/ double strtod_l #ifdef KR_headers (s00, se, loc) CONST char *s00; char **se; locale_t loc #else (CONST char *s00, char **se, locale_t loc) #endif
#define Check_FLT_ROUNDS #else #define Rounding Flt_Rounds #endif #ifdef Avoid_Underflow /*{*/ static double _DEFUN (sulp, (x, scale), U x _AND int scale) { U u; double rv; int i; rv = ulp(dval(x)); if (!scale || (i = 2*P + 1 - ((dword0(x) & Exp_mask) >> Exp_shift)) <= 0) return rv; /* Is there an example where i <= 0 ? */ dword0(u) = Exp_1 + ((__int32_t)i << Exp_shift); #ifndef _DOUBLE_IS_32BITS dword1(u) = 0; #endif return rv * u.d; } #endif /*}*/ #ifndef NO_HEX_FP static void _DEFUN (ULtod, (L, bits, exp, k),
inline typename tools::promote_args<T>::type ulp(const T& val) { return ulp(val, policies::policy<>()); }
strtodI(CONST char *s, char **sp, double *dd) #endif { static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; ULong bits[2], sign; Long exp; int j, k; U *u; k = strtodg(s, sp, &fpi, &exp, bits); u = (U*)dd; sign = k & STRTOG_Neg ? 0x80000000L : 0; switch(k & STRTOG_Retmask) { case STRTOG_NoNumber: dval(&u[0]) = dval(&u[1]) = 0.; break; case STRTOG_Zero: dval(&u[0]) = dval(&u[1]) = 0.; #ifdef Sudden_Underflow if (k & STRTOG_Inexact) { if (sign) word0(&u[0]) = 0x80100000L; else word0(&u[1]) = 0x100000L; } break; #else goto contain; #endif case STRTOG_Denormal: word1(&u[0]) = bits[0]; word0(&u[0]) = bits[1]; goto contain; case STRTOG_Normal: word1(&u[0]) = bits[0]; word0(&u[0]) = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); contain: j = k & STRTOG_Inexact; if (sign) { word0(&u[0]) |= sign; j = STRTOG_Inexact - j; } switch(j) { case STRTOG_Inexlo: #ifdef Sudden_Underflow if ((u->L[_0] & 0x7ff00000) < 0x3500000) { word0(&u[1]) = word0(&u[0]) + 0x3500000; word1(&u[1]) = word1(&u[0]); dval(&u[1]) += ulp(&u[1]); word0(&u[1]) -= 0x3500000; if (!(word0(&u[1]) & 0x7ff00000)) { word0(&u[1]) = sign; word1(&u[1]) = 0; } } else #endif dval(&u[1]) = dval(&u[0]) + ulp(&u[0]); break; case STRTOG_Inexhi: dval(&u[1]) = dval(&u[0]); #ifdef Sudden_Underflow if ((word0(&u[0]) & 0x7ff00000) < 0x3500000) { word0(&u[0]) += 0x3500000; dval(&u[0]) -= ulpdown(u); word0(&u[0]) -= 0x3500000; if (!(word0(&u[0]) & 0x7ff00000)) { word0(&u[0]) = sign; word1(&u[0]) = 0; } } else #endif dval(&u[0]) -= ulpdown(u); break; default: dval(&u[1]) = dval(&u[0]); } break; case STRTOG_Infinite: word0(&u[0]) = word0(&u[1]) = sign | 0x7ff00000; word1(&u[0]) = word1(&u[1]) = 0; if (k & STRTOG_Inexact) { if (sign) { word0(&u[1]) = 0xffefffffL; word1(&u[1]) = 0xffffffffL; } else { word0(&u[0]) = 0x7fefffffL; word1(&u[0]) = 0xffffffffL; } } break; case STRTOG_NaN: u->L[0] = (u+1)->L[0] = d_QNAN0; u->L[1] = (u+1)->L[1] = d_QNAN1; break; case STRTOG_NaNbits: word0(&u[0]) = word0(&u[1]) = 0x7ff00000 | sign | bits[1]; word1(&u[0]) = word1(&u[1]) = bits[0]; } return k; }