Lines Matching +full:ulp +full:- +full:0
2 * Generic functions for ULP error estimation.
4 * Copyright (c) 2019-2024, Arm Limited.
5 * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
21 mpfr_exp_t e = mpfr_get_exp (x) - RT(prec);
23 e = RT(emin) - 1;
24 if (e > RT(emax) - RT(prec))
25 e = RT(emax) - RT(prec);
29 return RT(emin) - 1;
31 return RT(emax) - RT(prec);
33 return 0;
39 rounded result the difference is 0. */
43 RT(float) want = p->y;
50 /* Ignore sign of NaN, and signalling-ness for MPFR. */
52 return 0;
54 return RT (issignaling) (got) == RT (issignaling) (want) ? 0 : INFINITY;
58 /* Fall through to ULP calculation if ignoring sign of zero and at
59 exactly one of want and got is non-zero. */
62 if (!ignore_zero_sign || (want != 0 && got != 0))
70 return 0;
86 ? got - want - tail ulp - 0.5 ulp
87 : got - want - tail ulp + 0.5 ulp. */
88 d = got - want;
89 e = d > 0 ? -p->tail - 0.5 : -p->tail + 0.5;
96 d = got - want;
97 e = -p->tail;
99 return RT(scalbn) (d, -p->ulpexp) + e;
106 && ((exgot ^ exwant) & ~exmay) == 0;
135 *ex = 0;
150 p->y = (RT(float)) yl;
151 volatile RT(float) vy = p->y; // TODO: barrier
153 p->ex = fetestexcept (FE_ALL_EXCEPT);
156 p->ex_may = FE_INEXACT;
157 if (RT(isok) (ygot, exgot, p->y, p->ex, p->ex_may))
159 p->ulpexp = RT(ulpscale) (p->y);
160 if (isinf (p->y))
161 p->tail = RT(lscalbn) (yl - (RT(double)) 2 * RT(halfinf), -p->ulpexp);
163 p->tail = RT(lscalbn) (yl - p->y, -p->ulpexp);
164 if (RT(fabs) (p->y) < RT(min_normal))
168 if (p->y != 0 || (p->ex & FE_INEXACT))
169 p->ex |= FE_UNDERFLOW | FE_INEXACT;
171 return 0;
180 p->y = (RT(float)) yl;
183 if (RT(isok_nofenv) (ygot, p->y))
185 p->ulpexp = RT(ulpscale) (p->y);
186 if (isinf (p->y))
187 p->tail = RT(lscalbn) (yl - (RT(double)) 2 * RT(halfinf), -p->ulpexp);
189 p->tail = RT(lscalbn) (yl - p->y, -p->ulpexp);
190 return 0;
226 p->y = mpfr_get_d (mr, r);
227 p->ex = t ? FE_INEXACT : 0;
228 p->ex_may = FE_INEXACT;
229 if (mpfr_underflow_p () && (p->ex & FE_INEXACT))
231 p->ex |= FE_UNDERFLOW;
233 p->ex |= FE_OVERFLOW | FE_INEXACT;
235 p->ex |= FE_DIVBYZERO;
237 // p->ex |= FE_INVALID;
238 if (!mpfr_nanflag_p () && RT(isok) (ygot, exgot, p->y, p->ex, p->ex_may))
241 p->ex |= FE_INVALID;
242 p->ulpexp = RT(ulpscale_mpfr) (my, t);
243 if (!isfinite (p->y))
245 p->tail = 0;
246 if (isnan (p->y))
249 p->y = T(sum) (a);
250 if (!isnan (p->y))
251 p->y = (p->y - p->y) / (p->y - p->y);
252 return RT(isok) (ygot, exgot, p->y, p->ex, p->ex_may);
254 mpfr_set_si_2exp (mr, signbit (p->y) ? -1 : 1, 1024, MPFR_RNDN);
255 if (mpfr_cmpabs (my, mr) >= 0)
256 return RT(isok) (ygot, exgot, p->y, p->ex, p->ex_may);
259 mpfr_mul_2si (me, me, -p->ulpexp, MPFR_RNDN);
260 p->tail = mpfr_get_d (me, MPFR_RNDN);
261 return 0;
270 double maxerr = 0;
271 uint64_t cnt = 0;
272 uint64_t cnt1 = 0;
273 uint64_t cnt2 = 0;
274 uint64_t cntfail = 0;
275 int r = conf->r;
276 int use_mpfr = conf->mpfr;
277 int fenv = conf->fenv;
287 int fail = 0;
292 if (f->twice) {
298 secondcall = 0;
314 int print = 0;
315 double err = RT (ulperr) (ygot, &want, r, conf->ignore_zero_sign);
318 if (abserr > 0)
322 if (abserr > conf->errlim)
334 if (!conf->quiet && abserr > conf->softlim)
340 // TODO: inf ulp handling
341 printf (" got %a want %a %+g ulp err %g\n", ygot, want.y,
344 int diff = fenv ? exgot ^ want.ex : 0;
353 printf (" is %a %+g ulp, got except 0x%0x", want.y, want.tail,
356 printf (" wrongly set: 0x%x", diff & exgot);
358 printf (" wrongly clear: 0x%x", diff & ~exgot);
362 if (cnt >= conf->n)
364 if (!conf->quiet && cnt % 0x100000 == 0)
367 100.0 * cnt / conf->n, (unsigned long long) cnt,
379 conf->rc, conf->errlim,
380 maxerr, conf->r == FE_TONEAREST ? "+0.5" : "+1.0",