9 case RN: return MPFR_RNDN;
10 case RZ: return MPFR_RNDZ;
11 case RD: return MPFR_RNDD;
12 case RU: return MPFR_RNDU;
17 enum {FLT, DBL, LDBL};
18 static const int emin[] = {
23 static const int emax[] = {
31 mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
36 round x into y considering x is already rounded (t = up or down)
38 only cases where adjustment is done:
39 x=...|1...0, t=up -> x=nextbelow(x)
40 x=...|1...0, t=down -> x=nextabove(x)
41 where | is the rounding point, ... is 0 or 1 bit patterns
44 // TODO: adjust(y, 0, 2, RN); when prec is 24 (0 vs 0x1p-149f), special case x=0
45 static int adjust_round(mpfr_t y, mpfr_t x, int t, int r)
51 xp = mpfr_get_prec(x);
52 yp = mpfr_get_prec(y);
53 if (yp >= xp || r != MPFR_RNDN || t == 0 || !mpfr_number_p(x) || mpfr_zero_p(x)) {
54 t2 = mpfr_set(y, x, r);
59 q = p + (xp + mp_bits_per_limb - 1)/mp_bits_per_limb - (yp + mp_bits_per_limb - 1)/mp_bits_per_limb;
60 if ((*p & 1 << -xp%mp_bits_per_limb) || !(*q & 1 << -yp%mp_bits_per_limb)) {
61 t2 = mpfr_set(y, x, r);
68 return mpfr_set(y, x, r);
71 static int adjust(mpfr_t mr, mpfr_t my, int t, int r, int type)
74 //printf("adj %d\n", t);
76 t = adjust_round(mr, my, t, r);
77 //printf("rnd %d\n", t);
79 mpfr_set_emin(emin[type]);
80 mpfr_set_emax(emax[type]);
81 // mpfr could handle this in subnormlize easily but no it doesnt...
82 t = mpfr_check_range(mr, t, r);
83 t = mpfr_subnormalize(mr, t, r);
84 mpfr_set_emax(MPFR_EMAX_DEFAULT);
85 mpfr_set_emin(MPFR_EMIN_DEFAULT);
86 //printf("sub %d\n", t);
88 // d = mpfr_get_d(mr, r);
89 // dn = nextafter(d, INFINITY);
90 // dp = nextafter(d, -INFINITY);
91 //printf("c\n %.21e %a\n %.21e %a\n %.21e %a\n",d,d,dn,dn,dp,dp);
92 // dn = nextafterf(d, INFINITY);
93 // dp = nextafterf(d, -INFINITY);
94 //printf("cf\n %.21e %a\n %.21e %a\n %.21e %a\n",d,d,dn,dn,dp,dp);
99 //static int eflags(mpfr_t mr, mpfr_t my, int t)
100 static int eflags(int naninput)
104 if (mpfr_inexflag_p())
106 // if (mpfr_underflow_p() && (t || mpfr_cmp(mr, my) != 0))
107 if (mpfr_underflow_p() && i)
109 if (mpfr_overflow_p())
113 if (!naninput && (mpfr_nanflag_p() || mpfr_erangeflag_p()))
118 static void genf(struct t *p, mpfr_t my, int t, int r)
120 MPFR_DECL_INIT(mr, 24);
123 t = adjust(mr, my, t, r, FLT);
124 p->y = mpfr_get_flt(mr, r);
125 p->e = eflags(isnan(p->x) || isnan(p->x2) || isnan(p->x3));
127 if (!isfinite(p->y)) {
130 mpfr_sub(my, mr, my, MPFR_RNDN);
131 mpfr_div_2si(my, my, i, MPFR_RNDN);
132 p->dy = mpfr_get_flt(my, MPFR_RNDN);
133 // happens in RU,RD,RZ modes when y is finite but outside the domain
141 static int mpf1(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, mpfr_rnd_t))
145 MPFR_DECL_INIT(mx, 24);
146 MPFR_DECL_INIT(my, 128);
149 mpfr_set_flt(mx, p->x, MPFR_RNDN);
156 static int mpf2(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t))
160 MPFR_DECL_INIT(mx, 24);
161 MPFR_DECL_INIT(mx2, 24);
162 MPFR_DECL_INIT(my, 128);
165 mpfr_set_flt(mx, p->x, MPFR_RNDN);
166 mpfr_set_flt(mx2, p->x2, MPFR_RNDN);
167 tn = fmp(my, mx, mx2, r);
172 static void gend(struct t *p, mpfr_t my, int t, int r)
174 MPFR_DECL_INIT(mr, 53);
177 t = adjust(mr, my, t, r, DBL);
178 p->y = mpfr_get_d(mr, r);
179 p->e = eflags(isnan(p->x) || isnan(p->x2) || isnan(p->x3));
181 if (!isfinite(p->y)) {
184 mpfr_sub(my, mr, my, MPFR_RNDN);
185 mpfr_div_2si(my, my, i, MPFR_RNDN);
186 p->dy = mpfr_get_flt(my, MPFR_RNDN);
187 // happens in RU,RD,RZ modes when y is finite but outside the domain
195 static int mpd1(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, mpfr_rnd_t))
199 MPFR_DECL_INIT(mx, 53);
200 MPFR_DECL_INIT(my, 128);
203 mpfr_set_d(mx, p->x, MPFR_RNDN);
210 static int mpd2(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t))
214 MPFR_DECL_INIT(mx, 53);
215 MPFR_DECL_INIT(mx2, 53);
216 MPFR_DECL_INIT(my, 128);
219 mpfr_set_d(mx, p->x, MPFR_RNDN);
220 mpfr_set_d(mx2, p->x2, MPFR_RNDN);
221 tn = fmp(my, mx, mx2, r);
226 #if LDBL_MANT_DIG == 64
227 static void genl(struct t *p, mpfr_t my, int t, int r)
229 MPFR_DECL_INIT(mr, 64);
232 t = adjust(mr, my, t, r, LDBL);
233 p->y = mpfr_get_ld(mr, r);
234 p->e = eflags(isnan(p->x) || isnan(p->x2) || isnan(p->x3));
236 if (!isfinite(p->y)) {
239 mpfr_sub(my, mr, my, MPFR_RNDN);
240 mpfr_div_2si(my, my, i, MPFR_RNDN);
241 p->dy = mpfr_get_flt(my, MPFR_RNDN);
242 // happens in RU,RD,RZ modes when y is finite but outside the domain
251 static int mpl1(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, mpfr_rnd_t))
253 #if LDBL_MANT_DIG == 53
255 #elif LDBL_MANT_DIG == 64
258 MPFR_DECL_INIT(mx, 64);
259 MPFR_DECL_INIT(my, 128);
262 mpfr_set_ld(mx, p->x, MPFR_RNDN);
272 static int mpl2(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t))
274 #if LDBL_MANT_DIG == 53
276 #elif LDBL_MANT_DIG == 64
279 MPFR_DECL_INIT(mx, 64);
280 MPFR_DECL_INIT(mx2, 64);
281 MPFR_DECL_INIT(my, 128);
284 mpfr_set_ld(mx, p->x, MPFR_RNDN);
285 mpfr_set_ld(mx2, p->x2, MPFR_RNDN);
286 tn = fmp(my, mx, mx2, r);
295 static int mplgamma_sign;
296 static int wrap_lgamma(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
298 return mpfr_lgamma(my, &mplgamma_sign, mx, r);
300 static long mpremquo_q;
301 static int wrap_remquo(mpfr_t my, const mpfr_t mx, const mpfr_t mx2, mpfr_rnd_t r)
303 return mpfr_remquo(my, &mpremquo_q, mx, mx2, r);
305 static int mpbessel_n;
306 static int wrap_jn(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
308 return mpfr_jn(my, mpbessel_n, mx, r);
310 static int wrap_yn(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
312 return mpfr_yn(my, mpbessel_n, mx, r);
314 static int wrap_ceil(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
316 return mpfr_ceil(my, mx);
318 static int wrap_floor(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
320 return mpfr_floor(my, mx);
322 static int wrap_round(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
324 return mpfr_round(my, mx);
326 static int wrap_trunc(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
328 return mpfr_trunc(my, mx);
330 static int wrap_nearbyint(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
332 int i = mpfr_rint(my, mx, r);
333 mpfr_clear_inexflag();
336 static int wrap_pow10(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
338 return mpfr_ui_pow(my, 10, mx, r);
342 static int wrap_sinpi(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
344 // hack because mpfr has no sinpi
345 MPFR_DECL_INIT(mz, 4096);
346 mpfr_const_pi(mz, r);
347 mpfr_mul(mz,mz,mx,r);
348 return mpfr_sin(my, mz, r);
350 int mpsinpi(struct t *t) { return mpd1(t, wrap_sinpi); }
352 int mpadd(struct t *t) { return mpd2(t, mpfr_add); }
353 int mpmul(struct t *t) { return mpd2(t, mpfr_mul); }
354 int mpdiv(struct t *t) { return mpd2(t, mpfr_div); }
356 int mpacos(struct t *t) { return mpd1(t, mpfr_acos); }
357 int mpacosf(struct t *t) { return mpf1(t, mpfr_acos); }
358 int mpacosl(struct t *t) { return mpl1(t, mpfr_acos); }
359 int mpacosh(struct t *t) { return mpd1(t, mpfr_acosh); }
360 int mpacoshf(struct t *t) { return mpf1(t, mpfr_acosh); }
361 int mpacoshl(struct t *t) { return mpl1(t, mpfr_acosh); }
362 int mpasin(struct t *t) { return mpd1(t, mpfr_asin); }
363 int mpasinf(struct t *t) { return mpf1(t, mpfr_asin); }
364 int mpasinl(struct t *t) { return mpl1(t, mpfr_asin); }
365 int mpasinh(struct t *t) { return mpd1(t, mpfr_asinh); }
366 int mpasinhf(struct t *t) { return mpf1(t, mpfr_asinh); }
367 int mpasinhl(struct t *t) { return mpl1(t, mpfr_asinh); }
368 int mpatan(struct t *t) { return mpd1(t, mpfr_atan); }
369 int mpatanf(struct t *t) { return mpf1(t, mpfr_atan); }
370 int mpatanl(struct t *t) { return mpl1(t, mpfr_atan); }
371 int mpatan2(struct t *t) { return mpd2(t, mpfr_atan2); }
372 int mpatan2f(struct t *t) { return mpf2(t, mpfr_atan2); }
373 int mpatan2l(struct t *t) { return mpl2(t, mpfr_atan2); }
374 int mpatanh(struct t *t) { return mpd1(t, mpfr_atanh); }
375 int mpatanhf(struct t *t) { return mpf1(t, mpfr_atanh); }
376 int mpatanhl(struct t *t) { return mpl1(t, mpfr_atanh); }
377 int mpcbrt(struct t *t) { return mpd1(t, mpfr_cbrt); }
378 int mpcbrtf(struct t *t) { return mpf1(t, mpfr_cbrt); }
379 int mpcbrtl(struct t *t) { return mpl1(t, mpfr_cbrt); }
380 int mpceil(struct t *t) { return mpd1(t, wrap_ceil); }
381 int mpceilf(struct t *t) { return mpf1(t, wrap_ceil); }
382 int mpceill(struct t *t) { return mpl1(t, wrap_ceil); }
383 int mpcopysign(struct t *t) { return mpd2(t, mpfr_copysign); }
384 int mpcopysignf(struct t *t) { return mpf2(t, mpfr_copysign); }
385 int mpcopysignl(struct t *t) { return mpl2(t, mpfr_copysign); }
386 int mpcos(struct t *t) { return mpd1(t, mpfr_cos); }
387 int mpcosf(struct t *t) { return mpf1(t, mpfr_cos); }
388 int mpcosl(struct t *t) { return mpl1(t, mpfr_cos); }
389 int mpcosh(struct t *t) { return mpd1(t, mpfr_cosh); }
390 int mpcoshf(struct t *t) { return mpf1(t, mpfr_cosh); }
391 int mpcoshl(struct t *t) { return mpl1(t, mpfr_cosh); }
392 int mperf(struct t *t) { return mpd1(t, mpfr_erf); }
393 int mperff(struct t *t) { return mpf1(t, mpfr_erf); }
394 int mperfl(struct t *t) { return mpl1(t, mpfr_erf); }
395 int mperfc(struct t *t) { return mpd1(t, mpfr_erfc); }
396 int mperfcf(struct t *t) { return mpf1(t, mpfr_erfc); }
397 int mperfcl(struct t *t) { return mpl1(t, mpfr_erfc); }
398 int mpexp(struct t *t) { return mpd1(t, mpfr_exp); }
399 int mpexpf(struct t *t) { return mpf1(t, mpfr_exp); }
400 int mpexpl(struct t *t) { return mpl1(t, mpfr_exp); }
401 int mpexp2(struct t *t) { return mpd1(t, mpfr_exp2); }
402 int mpexp2f(struct t *t) { return mpf1(t, mpfr_exp2); }
403 int mpexp2l(struct t *t) { return mpl1(t, mpfr_exp2); }
404 int mpexpm1(struct t *t) { return mpd1(t, mpfr_expm1); }
405 int mpexpm1f(struct t *t) { return mpf1(t, mpfr_expm1); }
406 int mpexpm1l(struct t *t) { return mpl1(t, mpfr_expm1); }
407 int mpfabs(struct t *t) { return mpd1(t, mpfr_abs); }
408 int mpfabsf(struct t *t) { return mpf1(t, mpfr_abs); }
409 int mpfabsl(struct t *t) { return mpl1(t, mpfr_abs); }
410 int mpfdim(struct t *t) { return mpd2(t, mpfr_dim); }
411 int mpfdimf(struct t *t) { return mpf2(t, mpfr_dim); }
412 int mpfdiml(struct t *t) { return mpl2(t, mpfr_dim); }
413 int mpfloor(struct t *t) { return mpd1(t, wrap_floor); }
414 int mpfloorf(struct t *t) { return mpf1(t, wrap_floor); }
415 int mpfloorl(struct t *t) { return mpl1(t, wrap_floor); }
416 int mpfmax(struct t *t) { return mpd2(t, mpfr_max); }
417 int mpfmaxf(struct t *t) { return mpf2(t, mpfr_max); }
418 int mpfmaxl(struct t *t) { return mpl2(t, mpfr_max); }
419 int mpfmin(struct t *t) { return mpd2(t, mpfr_min); }
420 int mpfminf(struct t *t) { return mpf2(t, mpfr_min); }
421 int mpfminl(struct t *t) { return mpl2(t, mpfr_min); }
422 int mpfmod(struct t *t) { return mpd2(t, mpfr_fmod); }
423 int mpfmodf(struct t *t) { return mpf2(t, mpfr_fmod); }
424 int mpfmodl(struct t *t) { return mpl2(t, mpfr_fmod); }
425 int mphypot(struct t *t) { return mpd2(t, mpfr_hypot); }
426 int mphypotf(struct t *t) { return mpf2(t, mpfr_hypot); }
427 int mphypotl(struct t *t) { return mpl2(t, mpfr_hypot); }
428 int mplgamma(struct t *t) { return mpd1(t, wrap_lgamma) || (t->i = mplgamma_sign, 0); }
429 int mplgammaf(struct t *t) { return mpf1(t, wrap_lgamma) || (t->i = mplgamma_sign, 0); }
430 int mplgammal(struct t *t) { return mpl1(t, wrap_lgamma) || (t->i = mplgamma_sign, 0); }
431 int mplog(struct t *t) { return mpd1(t, mpfr_log); }
432 int mplogf(struct t *t) { return mpf1(t, mpfr_log); }
433 int mplogl(struct t *t) { return mpl1(t, mpfr_log); }
434 int mplog10(struct t *t) { return mpd1(t, mpfr_log10); }
435 int mplog10f(struct t *t) { return mpf1(t, mpfr_log10); }
436 int mplog10l(struct t *t) { return mpl1(t, mpfr_log10); }
437 int mplog1p(struct t *t) { return mpd1(t, mpfr_log1p); }
438 int mplog1pf(struct t *t) { return mpf1(t, mpfr_log1p); }
439 int mplog1pl(struct t *t) { return mpl1(t, mpfr_log1p); }
440 int mplog2(struct t *t) { return mpd1(t, mpfr_log2); }
441 int mplog2f(struct t *t) { return mpf1(t, mpfr_log2); }
442 int mplog2l(struct t *t) { return mpl1(t, mpfr_log2); }
443 int mplogb(struct t *t)
445 MPFR_DECL_INIT(mx, 53);
462 mpfr_set_d(mx, t->x, MPFR_RNDN);
463 t->y = mpfr_get_exp(mx) - 1;
466 int mplogbf(struct t *t)
468 MPFR_DECL_INIT(mx, 24);
485 mpfr_set_flt(mx, t->x, MPFR_RNDN);
486 t->y = mpfr_get_exp(mx) - 1;
489 int mplogbl(struct t *t)
491 MPFR_DECL_INIT(mx, 64);
508 mpfr_set_ld(mx, t->x, MPFR_RNDN);
509 t->y = mpfr_get_exp(mx) - 1;
512 int mpnearbyint(struct t *t) { return mpd1(t, wrap_nearbyint) || (t->e&=~INEXACT, 0); }
513 int mpnearbyintf(struct t *t) { return mpf1(t, wrap_nearbyint) || (t->e&=~INEXACT, 0); }
514 int mpnearbyintl(struct t *t) { return mpl1(t, wrap_nearbyint) || (t->e&=~INEXACT, 0); }
515 // TODO: hard to implement with mpfr
516 int mpnextafter(struct t *t)
518 feclearexcept(FE_ALL_EXCEPT);
519 t->y = nextafter(t->x, t->x2);
524 int mpnextafterf(struct t *t)
526 feclearexcept(FE_ALL_EXCEPT);
527 t->y = nextafterf(t->x, t->x2);
532 int mpnextafterl(struct t *t)
534 feclearexcept(FE_ALL_EXCEPT);
535 t->y = nextafterl(t->x, t->x2);
540 int mpnexttoward(struct t *t)
542 feclearexcept(FE_ALL_EXCEPT);
543 t->y = nexttoward(t->x, t->x2);
548 int mpnexttowardf(struct t *t)
550 feclearexcept(FE_ALL_EXCEPT);
551 t->y = nexttowardf(t->x, t->x2);
556 int mpnexttowardl(struct t *t) { return mpnextafterl(t); }
557 int mppow(struct t *t) { return mpd2(t, mpfr_pow); }
558 int mppowf(struct t *t) { return mpf2(t, mpfr_pow); }
559 int mppowl(struct t *t) { return mpl2(t, mpfr_pow); }
560 int mpremainder(struct t *t) { return mpd2(t, mpfr_remainder); }
561 int mpremainderf(struct t *t) { return mpf2(t, mpfr_remainder); }
562 int mpremainderl(struct t *t) { return mpl2(t, mpfr_remainder); }
563 int mprint(struct t *t) { return mpd1(t, mpfr_rint); }
564 int mprintf(struct t *t) { return mpf1(t, mpfr_rint); }
565 int mprintl(struct t *t) { return mpl1(t, mpfr_rint); }
566 int mpround(struct t *t) { return mpd1(t, wrap_round); }
567 int mproundf(struct t *t) { return mpf1(t, wrap_round); }
568 int mproundl(struct t *t) { return mpl1(t, wrap_round); }
569 int mpsin(struct t *t) { return mpd1(t, mpfr_sin); }
570 int mpsinf(struct t *t) { return mpf1(t, mpfr_sin); }
571 int mpsinl(struct t *t) { return mpl1(t, mpfr_sin); }
572 int mpsinh(struct t *t) { return mpd1(t, mpfr_sinh); }
573 int mpsinhf(struct t *t) { return mpf1(t, mpfr_sinh); }
574 int mpsinhl(struct t *t) { return mpl1(t, mpfr_sinh); }
575 int mpsqrt(struct t *t) { return mpd1(t, mpfr_sqrt); }
576 int mpsqrtf(struct t *t) { return mpf1(t, mpfr_sqrt); }
577 int mpsqrtl(struct t *t) { return mpl1(t, mpfr_sqrt); }
578 int mptan(struct t *t) { return mpd1(t, mpfr_tan); }
579 int mptanf(struct t *t) { return mpf1(t, mpfr_tan); }
580 int mptanl(struct t *t) { return mpl1(t, mpfr_tan); }
581 int mptanh(struct t *t) { return mpd1(t, mpfr_tanh); }
582 int mptanhf(struct t *t) { return mpf1(t, mpfr_tanh); }
583 int mptanhl(struct t *t) { return mpl1(t, mpfr_tanh); }
584 // TODO: tgamma(2) raises wrong flags
585 int mptgamma(struct t *t) { return mpd1(t, mpfr_gamma); }
586 int mptgammaf(struct t *t) { return mpf1(t, mpfr_gamma); }
587 int mptgammal(struct t *t) { return mpl1(t, mpfr_gamma); }
588 int mptrunc(struct t *t) { return mpd1(t, wrap_trunc); }
589 int mptruncf(struct t *t) { return mpf1(t, wrap_trunc); }
590 int mptruncl(struct t *t) { return mpl1(t, wrap_trunc); }
591 int mpj0(struct t *t) { return mpd1(t, mpfr_j0); }
592 int mpj1(struct t *t) { return mpd1(t, mpfr_j1); }
593 int mpy0(struct t *t) { return mpd1(t, mpfr_y0); }
594 int mpy1(struct t *t) { return mpd1(t, mpfr_y1); }
595 // TODO: non standard functions
596 int mpscalb(struct t *t)
599 t->y = scalb(t->x, t->x2);
604 int mpscalbf(struct t *t)
607 t->y = scalbf(t->x, t->x2);
612 int mpj0f(struct t *t) { return mpf1(t, mpfr_j0); }
613 int mpj0l(struct t *t) { return mpl1(t, mpfr_j0); }
614 int mpj1f(struct t *t) { return mpf1(t, mpfr_j1); }
615 int mpj1l(struct t *t) { return mpl1(t, mpfr_j1); }
616 int mpy0f(struct t *t) { return mpf1(t, mpfr_y0); }
617 int mpy0l(struct t *t) { return mpl1(t, mpfr_y0); }
618 int mpy1f(struct t *t) { return mpf1(t, mpfr_y1); }
619 int mpy1l(struct t *t) { return mpl1(t, mpfr_y1); }
620 int mpexp10(struct t *t) { return mpd1(t, wrap_pow10); }
621 int mpexp10f(struct t *t) { return mpf1(t, wrap_pow10); }
622 int mpexp10l(struct t *t) { return mpl1(t, wrap_pow10); }
623 int mppow10(struct t *t) { return mpd1(t, wrap_pow10); }
624 int mppow10f(struct t *t) { return mpf1(t, wrap_pow10); }
625 int mppow10l(struct t *t) { return mpl1(t, wrap_pow10); }
627 int mpfrexp(struct t *t)
631 MPFR_DECL_INIT(mx, 53);
636 mpfr_set_d(mx, t->x, MPFR_RNDN);
637 k = mpfr_frexp(&e, mx, mx, t->r);
638 t->y = mpfr_get_d(mx, MPFR_RNDN);
640 t->e = eflags(isnan(t->x));
644 int mpfrexpf(struct t *t)
648 MPFR_DECL_INIT(mx, 24);
653 mpfr_set_flt(mx, t->x, MPFR_RNDN);
654 k = mpfr_frexp(&e, mx, mx, t->r);
655 t->y = mpfr_get_flt(mx, MPFR_RNDN);
657 t->e = eflags(isnan(t->x));
661 int mpfrexpl(struct t *t)
665 MPFR_DECL_INIT(mx, 64);
670 mpfr_set_ld(mx, t->x, MPFR_RNDN);
671 k = mpfr_frexp(&e, mx, mx, t->r);
672 t->y = mpfr_get_ld(mx, MPFR_RNDN);
674 t->e = eflags(isnan(t->x));
678 int mpldexp(struct t *t)
681 MPFR_DECL_INIT(mx, 53);
686 mpfr_set_d(mx, t->x, MPFR_RNDN);
687 k = mpfr_mul_2si(mx, mx, t->i, t->r);
688 adjust(mx, mx, k, t->r, DBL);
689 t->y = mpfr_get_d(mx, MPFR_RNDN);
690 t->e = eflags(isnan(t->x));
694 int mpldexpf(struct t *t)
697 MPFR_DECL_INIT(mx, 24);
702 mpfr_set_flt(mx, t->x, MPFR_RNDN);
703 k = mpfr_mul_2si(mx, mx, t->i, t->r);
704 adjust(mx, mx, k, t->r, FLT);
705 t->y = mpfr_get_flt(mx, MPFR_RNDN);
706 t->e = eflags(isnan(t->x));
710 int mpldexpl(struct t *t)
713 MPFR_DECL_INIT(mx, 64);
718 mpfr_set_ld(mx, t->x, MPFR_RNDN);
719 k = mpfr_mul_2si(mx, mx, t->i, t->r);
720 adjust(mx, mx, k, t->r, LDBL);
721 t->y = mpfr_get_ld(mx, MPFR_RNDN);
722 t->e = eflags(isnan(t->x));
726 int mpscalbn(struct t *t) { return mpldexp(t); }
727 int mpscalbnf(struct t *t) { return mpldexpf(t); }
728 int mpscalbnl(struct t *t) { return mpldexpl(t); }
729 int mpscalbln(struct t *t) { return mpldexp(t); }
730 int mpscalblnf(struct t *t) { return mpldexpf(t); }
731 int mpscalblnl(struct t *t) { return mpldexpl(t); }
733 int mplgamma_r(struct t *t) { return mplgamma(t); }
734 int mplgammaf_r(struct t *t) { return mplgammaf(t); }
735 int mplgammal_r(struct t *t) { return mplgammal(t); }
737 int mpilogb(struct t *t)
739 MPFR_DECL_INIT(mx, 53);
741 mpfr_set_d(mx, t->x, MPFR_RNDN);
742 t->i = mpfr_get_exp(mx) - 1;
744 if (isinf(t->x) || isnan(t->x) || t->x == 0)
748 int mpilogbf(struct t *t)
750 MPFR_DECL_INIT(mx, 24);
752 mpfr_set_flt(mx, t->x, MPFR_RNDN);
753 t->i = mpfr_get_exp(mx) - 1;
755 if (isinf(t->x) || isnan(t->x) || t->x == 0)
759 int mpilogbl(struct t *t)
761 MPFR_DECL_INIT(mx, 64);
763 mpfr_set_ld(mx, t->x, MPFR_RNDN);
764 t->i = mpfr_get_exp(mx) - 1;
766 if (isinf(t->x) || isnan(t->x) || t->x == 0)
771 // TODO: ll* is hard to do with mpfr
773 int mp##n(struct t *t) \
777 t->e = getexcept(); \
778 if (t->e & INVALID) \
796 int mpmodf(struct t *t)
800 r = mpd1(t, wrap_trunc);
806 r = mpd1(t, mpfr_frac);
811 int mpmodff(struct t *t)
815 r = mpf1(t, wrap_trunc);
821 r = mpf1(t, mpfr_frac);
826 int mpmodfl(struct t *t)
830 r = mpl1(t, wrap_trunc);
836 r = mpl1(t, mpfr_frac);
841 int mpsincos(struct t *t)
845 r = mpd1(t, mpfr_cos);
851 r = mpd1(t, mpfr_sin);
856 int mpsincosf(struct t *t)
860 r = mpf1(t, mpfr_cos);
866 r = mpf1(t, mpfr_sin);
871 int mpsincosl(struct t *t)
875 r = mpl1(t, mpfr_cos);
881 r = mpl1(t, mpfr_sin);
886 int mpremquo(struct t *t) { return mpd2(t, wrap_remquo) || (t->i = mpremquo_q, 0); }
887 int mpremquof(struct t *t) { return mpf2(t, wrap_remquo) || (t->i = mpremquo_q, 0); }
888 int mpremquol(struct t *t) { return mpl2(t, wrap_remquo) || (t->i = mpremquo_q, 0); }
890 int mpfma(struct t *t)
894 MPFR_DECL_INIT(mx, 53);
895 MPFR_DECL_INIT(mx2, 53);
896 MPFR_DECL_INIT(mx3, 53);
897 MPFR_DECL_INIT(my, 128);
900 mpfr_set_d(mx, t->x, MPFR_RNDN);
901 mpfr_set_d(mx2, t->x2, MPFR_RNDN);
902 mpfr_set_d(mx3, t->x3, MPFR_RNDN);
903 tn = mpfr_fma(my, mx, mx2, mx3, r);
908 int mpfmaf(struct t *t)
912 MPFR_DECL_INIT(mx, 24);
913 MPFR_DECL_INIT(mx2, 24);
914 MPFR_DECL_INIT(mx3, 24);
915 MPFR_DECL_INIT(my, 128);
918 mpfr_set_flt(mx, t->x, MPFR_RNDN);
919 mpfr_set_flt(mx2, t->x2, MPFR_RNDN);
920 mpfr_set_flt(mx3, t->x3, MPFR_RNDN);
921 tn = mpfr_fma(my, mx, mx2, mx3, r);
926 int mpfmal(struct t *t)
928 #if LDBL_MANT_DIG == 53
930 #elif LDBL_MANT_DIG == 64
933 MPFR_DECL_INIT(mx, 64);
934 MPFR_DECL_INIT(mx2, 64);
935 MPFR_DECL_INIT(mx3, 64);
936 MPFR_DECL_INIT(my, 128);
939 mpfr_set_ld(mx, t->x, MPFR_RNDN);
940 mpfr_set_ld(mx2, t->x2, MPFR_RNDN);
941 mpfr_set_ld(mx3, t->x3, MPFR_RNDN);
942 tn = mpfr_fma(my, mx, mx2, mx3, r);
950 int mpjn(struct t *t) { mpbessel_n = t->i; return mpd1(t, wrap_jn); }
951 int mpjnf(struct t *t) { mpbessel_n = t->i; return mpf1(t, wrap_jn); }
952 int mpjnl(struct t *t) { mpbessel_n = t->i; return mpl1(t, wrap_jn); }
953 int mpyn(struct t *t) { mpbessel_n = t->i; return mpd1(t, wrap_yn); }
954 int mpynf(struct t *t) { mpbessel_n = t->i; return mpf1(t, wrap_yn); }
955 int mpynl(struct t *t) { mpbessel_n = t->i; return mpl1(t, wrap_yn); }