10 case RN: return MPFR_RNDN;
11 case RZ: return MPFR_RNDZ;
12 case RD: return MPFR_RNDD;
13 case RU: return MPFR_RNDU;
20 mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
34 #if LDBL_MANT_DIG == 64
37 mpfr_set_emin(-16444);
43 round x into y considering x is already rounded (t = up or down)
45 only cases where adjustment is done:
46 x=...|1...0, t=up -> x=nextbelow(x)
47 x=...|1...0, t=down -> x=nextabove(x)
48 where | is the rounding point, ... is 0 or 1 bit patterns
51 // TODO: adjust(y, 0, 2, RN); when prec is 24 (0 vs 0x1p-149f), special case x=0
52 static int adjust_round(mpfr_t y, mpfr_t x, int t, int r)
58 xp = mpfr_get_prec(x);
59 yp = mpfr_get_prec(y);
60 if (yp >= xp || r != MPFR_RNDN || t == 0 || !mpfr_number_p(x) || mpfr_zero_p(x)) {
61 t2 = mpfr_set(y, x, r);
66 q = p + (xp + mp_bits_per_limb - 1)/mp_bits_per_limb - (yp + mp_bits_per_limb - 1)/mp_bits_per_limb;
67 if ((*p & 1 << -xp%mp_bits_per_limb) || !(*q & 1 << -yp%mp_bits_per_limb)) {
68 t2 = mpfr_set(y, x, r);
75 return mpfr_set(y, x, r);
78 static int adjust(mpfr_t mr, mpfr_t my, int t, int r)
81 //printf("adj %d\n", t);
83 t = adjust_round(mr, my, t, r);
84 //printf("rnd %d\n", t);
86 t = mpfr_subnormalize(mr, t, r);
87 //printf("sub %d\n", t);
89 // d = mpfr_get_d(mr, r);
90 // dn = nextafter(d, INFINITY);
91 // dp = nextafter(d, -INFINITY);
92 //printf("c\n %.21e %a\n %.21e %a\n %.21e %a\n",d,d,dn,dn,dp,dp);
93 // dn = nextafterf(d, INFINITY);
94 // dp = nextafterf(d, -INFINITY);
95 //printf("cf\n %.21e %a\n %.21e %a\n %.21e %a\n",d,d,dn,dn,dp,dp);
100 //static int eflags(mpfr_t mr, mpfr_t my, int t)
101 static int eflags(int naninput)
105 if (mpfr_inexflag_p())
107 // if (mpfr_underflow_p() && (t || mpfr_cmp(mr, my) != 0))
108 if (mpfr_underflow_p() && i)
110 if (mpfr_overflow_p())
114 if (!naninput && (mpfr_nanflag_p() || mpfr_erangeflag_p()))
119 static void genf(struct t *p, mpfr_t my, int t, int r)
121 MPFR_DECL_INIT(mr, 24);
124 t = adjust(mr, my, t, r);
125 p->y = mpfr_get_flt(mr, r);
126 p->e = eflags(isnan(p->x) || isnan(p->x2) || isnan(p->x3));
128 if (!isfinite(p->y)) {
131 mpfr_div_2si(mr, mr, i, MPFR_RNDN);
132 mpfr_div_2si(my, my, i, MPFR_RNDN);
133 mpfr_sub(my, mr, my, MPFR_RNDN);
134 p->dy = mpfr_get_flt(my, r);
136 mpfr_sub(my, mr, my, MPFR_RNDN);
137 mpfr_div_2si(my, my, i, MPFR_RNDN);
138 p->dy = mpfr_get_flt(my, r);
142 static int mpf1(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, mpfr_rnd_t))
146 MPFR_DECL_INIT(mx, 24);
147 MPFR_DECL_INIT(my, 128);
151 mpfr_set_flt(mx, p->x, MPFR_RNDN);
155 if ((p->e & INEXACT) && nextafterf(p->y, 0) == 0) {
156 mpfr_set_emin(-(1<<20));
158 mpfr_mul_2si(my, my, 149, MPFR_RNDN);
159 p->dy = scalbnl(p->y, 149) - mpfr_get_ld(my, r);
165 static int mpf2(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t))
169 MPFR_DECL_INIT(mx, 24);
170 MPFR_DECL_INIT(mx2, 24);
171 MPFR_DECL_INIT(my, 128);
175 mpfr_set_flt(mx, p->x, MPFR_RNDN);
176 mpfr_set_flt(mx2, p->x2, MPFR_RNDN);
177 tn = fmp(my, mx, mx2, r);
179 if ((p->e & INEXACT) && nextafterf(p->y, 0) == 0) {
180 mpfr_set_emin(-(1<<20));
181 tn = fmp(my, mx, mx2, r);
182 mpfr_mul_2si(my, my, 149, MPFR_RNDN);
183 p->dy = scalbnl(p->y, 149) - mpfr_get_ld(my, r);
189 static void gend(struct t *p, mpfr_t my, int t, int r)
191 MPFR_DECL_INIT(mr, 53);
194 t = adjust(mr, my, t, r);
195 p->y = mpfr_get_d(mr, r);
196 p->e = eflags(isnan(p->x) || isnan(p->x2) || isnan(p->x3));
198 if (!isfinite(p->y)) {
201 mpfr_div_2si(mr, mr, i, MPFR_RNDN);
202 mpfr_div_2si(my, my, i, MPFR_RNDN);
203 mpfr_sub(my, mr, my, MPFR_RNDN);
204 p->dy = mpfr_get_flt(my, r);
206 mpfr_sub(my, mr, my, MPFR_RNDN);
207 mpfr_div_2si(my, my, i, MPFR_RNDN);
208 p->dy = mpfr_get_flt(my, r);
212 static int mpd1(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, mpfr_rnd_t))
216 MPFR_DECL_INIT(mx, 53);
217 MPFR_DECL_INIT(my, 128);
221 mpfr_set_d(mx, p->x, MPFR_RNDN);
223 //printf("underflow: %d\n", mpfr_underflow_p());
226 //printf("dy: %a %.3f\n", p->dy, p->dy);
227 if ((p->e & INEXACT) && nextafter(p->y, 0) == 0) {
228 mpfr_set_emin(-(1<<20));
230 mpfr_mul_2si(my, my, 1074, MPFR_RNDN);
232 p->dy = scalbnl(p->y, 1074) - mpfr_get_ld(my, r);
233 //printf("dy: %a %.3f\n", p->dy, p->dy);
234 mpfr_set_emin(-1073);
239 static int mpd2(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t))
243 MPFR_DECL_INIT(mx, 53);
244 MPFR_DECL_INIT(mx2, 53);
245 MPFR_DECL_INIT(my, 128);
249 mpfr_set_d(mx, p->x, MPFR_RNDN);
250 mpfr_set_d(mx2, p->x2, MPFR_RNDN);
251 tn = fmp(my, mx, mx2, r);
253 if ((p->e & INEXACT) && nextafter(p->y, 0) == 0) {
254 mpfr_set_emin(-(1<<20));
255 tn = fmp(my, mx, mx2, r);
256 mpfr_mul_2si(my, my, 1074, MPFR_RNDN);
257 p->dy = scalbnl(p->y, 1074) - mpfr_get_ld(my, r);
258 mpfr_set_emin(-1073);
263 #if LDBL_MANT_DIG == 64
264 static void genl(struct t *p, mpfr_t my, int t, int r)
266 MPFR_DECL_INIT(mr, 64);
269 t = adjust(mr, my, t, r);
270 p->y = mpfr_get_ld(mr, r);
271 p->e = eflags(isnan(p->x) || isnan(p->x2) || isnan(p->x3));
273 if (!isfinite(p->y)) {
276 mpfr_div_2si(mr, mr, i, MPFR_RNDN);
277 mpfr_div_2si(my, my, i, MPFR_RNDN);
278 mpfr_sub(my, mr, my, MPFR_RNDN);
279 p->dy = mpfr_get_flt(my, r);
281 mpfr_sub(my, mr, my, MPFR_RNDN);
282 mpfr_div_2si(my, my, i, MPFR_RNDN);
283 p->dy = mpfr_get_flt(my, r);
288 static int mpl1(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, mpfr_rnd_t))
290 #if LDBL_MANT_DIG == 53
292 #elif LDBL_MANT_DIG == 64
295 MPFR_DECL_INIT(mx, 64);
296 MPFR_DECL_INIT(my, 128);
300 mpfr_set_ld(mx, p->x, MPFR_RNDN);
304 if ((p->e & INEXACT) && nextafterl(p->y, 0) == 0) {
305 mpfr_set_emin(-(1<<20));
307 mpfr_mul_2si(my, my, 16445, MPFR_RNDN);
308 p->dy = scalbnl(p->y, 16445) - mpfr_get_ld(my, r);
309 mpfr_set_emin(-16444);
317 static int mpl2(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t))
319 #if LDBL_MANT_DIG == 53
321 #elif LDBL_MANT_DIG == 64
324 MPFR_DECL_INIT(mx, 64);
325 MPFR_DECL_INIT(mx2, 64);
326 MPFR_DECL_INIT(my, 128);
330 mpfr_set_ld(mx, p->x, MPFR_RNDN);
331 mpfr_set_ld(mx2, p->x2, MPFR_RNDN);
332 tn = fmp(my, mx, mx2, r);
334 if ((p->e & INEXACT) && nextafterl(p->y, 0) == 0) {
335 mpfr_set_emin(-(1<<20));
336 tn = fmp(my, mx, mx2, r);
337 mpfr_mul_2si(my, my, 16445, MPFR_RNDN);
338 p->dy = scalbnl(p->y, 16445) - mpfr_get_ld(my, r);
339 mpfr_set_emin(-16444);
348 static int mplgamma_sign;
349 static int wrap_lgamma(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
351 return mpfr_lgamma(my, &mplgamma_sign, mx, r);
353 static long mpremquo_q;
354 static int wrap_remquo(mpfr_t my, const mpfr_t mx, const mpfr_t mx2, mpfr_rnd_t r)
356 return mpfr_remquo(my, &mpremquo_q, mx, mx2, r);
358 static int mpbessel_n;
359 static int wrap_jn(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
361 return mpfr_jn(my, mpbessel_n, mx, r);
363 static int wrap_yn(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
365 return mpfr_yn(my, mpbessel_n, mx, r);
367 static int wrap_ceil(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
369 return mpfr_ceil(my, mx);
371 static int wrap_floor(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
373 return mpfr_floor(my, mx);
375 static int wrap_round(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
377 return mpfr_round(my, mx);
379 static int wrap_trunc(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
381 return mpfr_trunc(my, mx);
383 static int wrap_nearbyint(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
385 int i = mpfr_rint(my, mx, r);
386 mpfr_clear_inexflag();
389 static int wrap_pow10(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
391 return mpfr_ui_pow(my, 10, mx, r);
394 int mpadd(struct t *t) { return mpd2(t, mpfr_add); }
396 int mpacos(struct t *t) { return mpd1(t, mpfr_acos); }
397 int mpacosf(struct t *t) { return mpf1(t, mpfr_acos); }
398 int mpacosl(struct t *t) { return mpl1(t, mpfr_acos); }
399 int mpacosh(struct t *t) { return mpd1(t, mpfr_acosh); }
400 int mpacoshf(struct t *t) { return mpf1(t, mpfr_acosh); }
401 int mpacoshl(struct t *t) { return mpl1(t, mpfr_acosh); }
402 int mpasin(struct t *t) { return mpd1(t, mpfr_asin); }
403 int mpasinf(struct t *t) { return mpf1(t, mpfr_asin); }
404 int mpasinl(struct t *t) { return mpl1(t, mpfr_asin); }
405 int mpasinh(struct t *t) { return mpd1(t, mpfr_asinh); }
406 int mpasinhf(struct t *t) { return mpf1(t, mpfr_asinh); }
407 int mpasinhl(struct t *t) { return mpl1(t, mpfr_asinh); }
408 int mpatan(struct t *t) { return mpd1(t, mpfr_atan); }
409 int mpatanf(struct t *t) { return mpf1(t, mpfr_atan); }
410 int mpatanl(struct t *t) { return mpl1(t, mpfr_atan); }
411 int mpatan2(struct t *t) { return mpd2(t, mpfr_atan2); }
412 int mpatan2f(struct t *t) { return mpf2(t, mpfr_atan2); }
413 int mpatan2l(struct t *t) { return mpl2(t, mpfr_atan2); }
414 int mpatanh(struct t *t) { return mpd1(t, mpfr_atanh); }
415 int mpatanhf(struct t *t) { return mpf1(t, mpfr_atanh); }
416 int mpatanhl(struct t *t) { return mpl1(t, mpfr_atanh); }
417 int mpcbrt(struct t *t) { return mpd1(t, mpfr_cbrt); }
418 int mpcbrtf(struct t *t) { return mpf1(t, mpfr_cbrt); }
419 int mpcbrtl(struct t *t) { return mpl1(t, mpfr_cbrt); }
420 int mpceil(struct t *t) { return mpd1(t, wrap_ceil); }
421 int mpceilf(struct t *t) { return mpf1(t, wrap_ceil); }
422 int mpceill(struct t *t) { return mpl1(t, wrap_ceil); }
423 int mpcopysign(struct t *t) { return mpd2(t, mpfr_copysign); }
424 int mpcopysignf(struct t *t) { return mpf2(t, mpfr_copysign); }
425 int mpcopysignl(struct t *t) { return mpl2(t, mpfr_copysign); }
426 int mpcos(struct t *t) { return mpd1(t, mpfr_cos); }
427 int mpcosf(struct t *t) { return mpf1(t, mpfr_cos); }
428 int mpcosl(struct t *t) { return mpl1(t, mpfr_cos); }
429 int mpcosh(struct t *t) { return mpd1(t, mpfr_cosh); }
430 int mpcoshf(struct t *t) { return mpf1(t, mpfr_cosh); }
431 int mpcoshl(struct t *t) { return mpl1(t, mpfr_cosh); }
432 int mperf(struct t *t) { return mpd1(t, mpfr_erf); }
433 int mperff(struct t *t) { return mpf1(t, mpfr_erf); }
434 int mperfl(struct t *t) { return mpl1(t, mpfr_erf); }
435 int mperfc(struct t *t) { return mpd1(t, mpfr_erfc); }
436 int mperfcf(struct t *t) { return mpf1(t, mpfr_erfc); }
437 int mperfcl(struct t *t) { return mpl1(t, mpfr_erfc); }
438 int mpexp(struct t *t) { return mpd1(t, mpfr_exp); }
439 int mpexpf(struct t *t) { return mpf1(t, mpfr_exp); }
440 int mpexpl(struct t *t) { return mpl1(t, mpfr_exp); }
441 int mpexp2(struct t *t) { return mpd1(t, mpfr_exp2); }
442 int mpexp2f(struct t *t) { return mpf1(t, mpfr_exp2); }
443 int mpexp2l(struct t *t) { return mpl1(t, mpfr_exp2); }
444 int mpexpm1(struct t *t) { return mpd1(t, mpfr_expm1); }
445 int mpexpm1f(struct t *t) { return mpf1(t, mpfr_expm1); }
446 int mpexpm1l(struct t *t) { return mpl1(t, mpfr_expm1); }
447 int mpfabs(struct t *t) { return mpd1(t, mpfr_abs); }
448 int mpfabsf(struct t *t) { return mpf1(t, mpfr_abs); }
449 int mpfabsl(struct t *t) { return mpl1(t, mpfr_abs); }
450 int mpfdim(struct t *t) { return mpd2(t, mpfr_dim); }
451 int mpfdimf(struct t *t) { return mpf2(t, mpfr_dim); }
452 int mpfdiml(struct t *t) { return mpl2(t, mpfr_dim); }
453 int mpfloor(struct t *t) { return mpd1(t, wrap_floor); }
454 int mpfloorf(struct t *t) { return mpf1(t, wrap_floor); }
455 int mpfloorl(struct t *t) { return mpl1(t, wrap_floor); }
456 int mpfmax(struct t *t) { return mpd2(t, mpfr_max); }
457 int mpfmaxf(struct t *t) { return mpf2(t, mpfr_max); }
458 int mpfmaxl(struct t *t) { return mpl2(t, mpfr_max); }
459 int mpfmin(struct t *t) { return mpd2(t, mpfr_min); }
460 int mpfminf(struct t *t) { return mpf2(t, mpfr_min); }
461 int mpfminl(struct t *t) { return mpl2(t, mpfr_min); }
462 int mpfmod(struct t *t) { return mpd2(t, mpfr_fmod); }
463 int mpfmodf(struct t *t) { return mpf2(t, mpfr_fmod); }
464 int mpfmodl(struct t *t) { return mpl2(t, mpfr_fmod); }
465 int mphypot(struct t *t) { return mpd2(t, mpfr_hypot); }
466 int mphypotf(struct t *t) { return mpf2(t, mpfr_hypot); }
467 int mphypotl(struct t *t) { return mpl2(t, mpfr_hypot); }
468 int mplgamma(struct t *t) { return mpd1(t, wrap_lgamma) || (t->i = mplgamma_sign, 0); }
469 int mplgammaf(struct t *t) { return mpf1(t, wrap_lgamma) || (t->i = mplgamma_sign, 0); }
470 int mplgammal(struct t *t) { return mpl1(t, wrap_lgamma) || (t->i = mplgamma_sign, 0); }
471 int mplog(struct t *t) { return mpd1(t, mpfr_log); }
472 int mplogf(struct t *t) { return mpf1(t, mpfr_log); }
473 int mplogl(struct t *t) { return mpl1(t, mpfr_log); }
474 int mplog10(struct t *t) { return mpd1(t, mpfr_log10); }
475 int mplog10f(struct t *t) { return mpf1(t, mpfr_log10); }
476 int mplog10l(struct t *t) { return mpl1(t, mpfr_log10); }
477 int mplog1p(struct t *t) { return mpd1(t, mpfr_log1p); }
478 int mplog1pf(struct t *t) { return mpf1(t, mpfr_log1p); }
479 int mplog1pl(struct t *t) { return mpl1(t, mpfr_log1p); }
480 int mplog2(struct t *t) { return mpd1(t, mpfr_log2); }
481 int mplog2f(struct t *t) { return mpf1(t, mpfr_log2); }
482 int mplog2l(struct t *t) { return mpl1(t, mpfr_log2); }
483 int mplogb(struct t *t)
485 MPFR_DECL_INIT(mx, 53);
502 mpfr_set_d(mx, t->x, MPFR_RNDN);
503 t->y = mpfr_get_exp(mx) - 1;
506 int mplogbf(struct t *t)
508 MPFR_DECL_INIT(mx, 24);
525 mpfr_set_flt(mx, t->x, MPFR_RNDN);
526 t->y = mpfr_get_exp(mx) - 1;
529 int mplogbl(struct t *t)
531 MPFR_DECL_INIT(mx, 64);
548 mpfr_set_ld(mx, t->x, MPFR_RNDN);
549 t->y = mpfr_get_exp(mx) - 1;
552 int mpnearbyint(struct t *t) { return mpd1(t, wrap_nearbyint) || (t->e&=~INEXACT, 0); }
553 int mpnearbyintf(struct t *t) { return mpf1(t, wrap_nearbyint) || (t->e&=~INEXACT, 0); }
554 int mpnearbyintl(struct t *t) { return mpl1(t, wrap_nearbyint) || (t->e&=~INEXACT, 0); }
555 // TODO: hard to implement with mpfr
556 int mpnextafter(struct t *t)
558 feclearexcept(FE_ALL_EXCEPT);
559 t->y = nextafter(t->x, t->x2);
564 int mpnextafterf(struct t *t)
566 feclearexcept(FE_ALL_EXCEPT);
567 t->y = nextafterf(t->x, t->x2);
572 int mpnextafterl(struct t *t)
574 feclearexcept(FE_ALL_EXCEPT);
575 t->y = nextafterl(t->x, t->x2);
580 int mpnexttoward(struct t *t)
582 feclearexcept(FE_ALL_EXCEPT);
583 t->y = nexttoward(t->x, t->x2);
588 int mpnexttowardf(struct t *t)
590 feclearexcept(FE_ALL_EXCEPT);
591 t->y = nexttowardf(t->x, t->x2);
596 int mpnexttowardl(struct t *t) { return mpnextafterl(t); }
597 int mppow(struct t *t) { return mpd2(t, mpfr_pow); }
598 int mppowf(struct t *t) { return mpf2(t, mpfr_pow); }
599 int mppowl(struct t *t) { return mpl2(t, mpfr_pow); }
600 int mpremainder(struct t *t) { return mpd2(t, mpfr_remainder); }
601 int mpremainderf(struct t *t) { return mpf2(t, mpfr_remainder); }
602 int mpremainderl(struct t *t) { return mpl2(t, mpfr_remainder); }
603 int mprint(struct t *t) { return mpd1(t, mpfr_rint); }
604 int mprintf(struct t *t) { return mpf1(t, mpfr_rint); }
605 int mprintl(struct t *t) { return mpl1(t, mpfr_rint); }
606 int mpround(struct t *t) { return mpd1(t, wrap_round); }
607 int mproundf(struct t *t) { return mpf1(t, wrap_round); }
608 int mproundl(struct t *t) { return mpl1(t, wrap_round); }
609 int mpsin(struct t *t) { return mpd1(t, mpfr_sin); }
610 int mpsinf(struct t *t) { return mpf1(t, mpfr_sin); }
611 int mpsinl(struct t *t) { return mpl1(t, mpfr_sin); }
612 int mpsinh(struct t *t) { return mpd1(t, mpfr_sinh); }
613 int mpsinhf(struct t *t) { return mpf1(t, mpfr_sinh); }
614 int mpsinhl(struct t *t) { return mpl1(t, mpfr_sinh); }
615 int mpsqrt(struct t *t) { return mpd1(t, mpfr_sqrt); }
616 int mpsqrtf(struct t *t) { return mpf1(t, mpfr_sqrt); }
617 int mpsqrtl(struct t *t) { return mpl1(t, mpfr_sqrt); }
618 int mptan(struct t *t) { return mpd1(t, mpfr_tan); }
619 int mptanf(struct t *t) { return mpf1(t, mpfr_tan); }
620 int mptanl(struct t *t) { return mpl1(t, mpfr_tan); }
621 int mptanh(struct t *t) { return mpd1(t, mpfr_tanh); }
622 int mptanhf(struct t *t) { return mpf1(t, mpfr_tanh); }
623 int mptanhl(struct t *t) { return mpl1(t, mpfr_tanh); }
624 // TODO: tgamma(2) raises wrong flags
625 int mptgamma(struct t *t) { return mpd1(t, mpfr_gamma); }
626 int mptgammaf(struct t *t) { return mpf1(t, mpfr_gamma); }
627 int mptgammal(struct t *t) { return mpl1(t, mpfr_gamma); }
628 int mptrunc(struct t *t) { return mpd1(t, wrap_trunc); }
629 int mptruncf(struct t *t) { return mpf1(t, wrap_trunc); }
630 int mptruncl(struct t *t) { return mpl1(t, wrap_trunc); }
631 int mpj0(struct t *t) { return mpd1(t, mpfr_j0); }
632 int mpj1(struct t *t) { return mpd1(t, mpfr_j1); }
633 int mpy0(struct t *t) { return mpd1(t, mpfr_y0); }
634 int mpy1(struct t *t) { return mpd1(t, mpfr_y1); }
635 // TODO: non standard functions
636 int mpscalb(struct t *t)
639 t->y = scalb(t->x, t->x2);
644 int mpscalbf(struct t *t)
647 t->y = scalbf(t->x, t->x2);
652 int mpj0f(struct t *t) { return mpf1(t, mpfr_j0); }
653 int mpj0l(struct t *t) { return mpl1(t, mpfr_j0); }
654 int mpj1f(struct t *t) { return mpf1(t, mpfr_j1); }
655 int mpj1l(struct t *t) { return mpl1(t, mpfr_j1); }
656 int mpy0f(struct t *t) { return mpf1(t, mpfr_y0); }
657 int mpy0l(struct t *t) { return mpl1(t, mpfr_y0); }
658 int mpy1f(struct t *t) { return mpf1(t, mpfr_y1); }
659 int mpy1l(struct t *t) { return mpl1(t, mpfr_y1); }
660 int mpexp10(struct t *t) { return mpd1(t, wrap_pow10); }
661 int mpexp10f(struct t *t) { return mpf1(t, wrap_pow10); }
662 int mpexp10l(struct t *t) { return mpl1(t, wrap_pow10); }
663 int mppow10(struct t *t) { return mpd1(t, wrap_pow10); }
664 int mppow10f(struct t *t) { return mpf1(t, wrap_pow10); }
665 int mppow10l(struct t *t) { return mpl1(t, wrap_pow10); }
667 int mpfrexp(struct t *t)
671 MPFR_DECL_INIT(mx, 53);
677 mpfr_set_d(mx, t->x, MPFR_RNDN);
678 k = mpfr_frexp(&e, mx, mx, t->r);
679 mpfr_subnormalize(mx, k, t->r);
680 t->y = mpfr_get_d(mx, MPFR_RNDN);
682 t->e = eflags(isnan(t->x));
686 int mpfrexpf(struct t *t)
690 MPFR_DECL_INIT(mx, 24);
696 mpfr_set_flt(mx, t->x, MPFR_RNDN);
697 k = mpfr_frexp(&e, mx, mx, t->r);
698 mpfr_subnormalize(mx, k, t->r);
699 t->y = mpfr_get_flt(mx, MPFR_RNDN);
701 t->e = eflags(isnan(t->x));
705 int mpfrexpl(struct t *t)
709 MPFR_DECL_INIT(mx, 64);
715 mpfr_set_ld(mx, t->x, MPFR_RNDN);
716 k = mpfr_frexp(&e, mx, mx, t->r);
717 mpfr_subnormalize(mx, k, t->r);
718 t->y = mpfr_get_ld(mx, MPFR_RNDN);
720 t->e = eflags(isnan(t->x));
724 int mpldexp(struct t *t)
727 MPFR_DECL_INIT(mx, 53);
733 mpfr_set_d(mx, t->x, MPFR_RNDN);
734 k = mpfr_mul_2si(mx, mx, t->i, t->r);
735 mpfr_subnormalize(mx, k, t->r);
736 t->y = mpfr_get_d(mx, MPFR_RNDN);
737 t->e = eflags(isnan(t->x));
741 int mpldexpf(struct t *t)
744 MPFR_DECL_INIT(mx, 24);
750 mpfr_set_flt(mx, t->x, MPFR_RNDN);
751 k = mpfr_mul_2si(mx, mx, t->i, t->r);
752 mpfr_subnormalize(mx, k, t->r);
753 t->y = mpfr_get_flt(mx, MPFR_RNDN);
754 t->e = eflags(isnan(t->x));
758 int mpldexpl(struct t *t)
761 MPFR_DECL_INIT(mx, 64);
767 mpfr_set_ld(mx, t->x, MPFR_RNDN);
768 k = mpfr_mul_2si(mx, mx, t->i, t->r);
769 mpfr_subnormalize(mx, k, t->r);
770 t->y = mpfr_get_ld(mx, MPFR_RNDN);
771 t->e = eflags(isnan(t->x));
775 int mpscalbn(struct t *t) { return mpldexp(t); }
776 int mpscalbnf(struct t *t) { return mpldexpf(t); }
777 int mpscalbnl(struct t *t) { return mpldexpl(t); }
778 int mpscalbln(struct t *t) { return mpldexp(t); }
779 int mpscalblnf(struct t *t) { return mpldexpf(t); }
780 int mpscalblnl(struct t *t) { return mpldexpl(t); }
782 int mplgamma_r(struct t *t) { return mplgamma(t); }
783 int mplgammaf_r(struct t *t) { return mplgammaf(t); }
784 int mplgammal_r(struct t *t) { return mplgammal(t); }
786 int mpilogb(struct t *t)
788 MPFR_DECL_INIT(mx, 53);
790 mpfr_set_d(mx, t->x, MPFR_RNDN);
791 t->i = mpfr_get_exp(mx) - 1;
793 if (isinf(t->x) || isnan(t->x) || t->x == 0)
797 int mpilogbf(struct t *t)
799 MPFR_DECL_INIT(mx, 24);
801 mpfr_set_flt(mx, t->x, MPFR_RNDN);
802 t->i = mpfr_get_exp(mx) - 1;
804 if (isinf(t->x) || isnan(t->x) || t->x == 0)
808 int mpilogbl(struct t *t)
810 MPFR_DECL_INIT(mx, 64);
812 mpfr_set_ld(mx, t->x, MPFR_RNDN);
813 t->i = mpfr_get_exp(mx) - 1;
815 if (isinf(t->x) || isnan(t->x) || t->x == 0)
820 // TODO: ll* is hard to do with mpfr
822 int mp##n(struct t *t) \
826 t->e = getexcept(); \
843 int mpmodf(struct t *t)
847 r = mpd1(t, wrap_trunc);
853 r = mpd1(t, mpfr_frac);
858 int mpmodff(struct t *t)
862 r = mpf1(t, wrap_trunc);
868 r = mpf1(t, mpfr_frac);
873 int mpmodfl(struct t *t)
877 r = mpl1(t, wrap_trunc);
883 r = mpl1(t, mpfr_frac);
888 int mpsincos(struct t *t)
892 r = mpd1(t, mpfr_cos);
898 r = mpd1(t, mpfr_sin);
903 int mpsincosf(struct t *t)
907 r = mpf1(t, mpfr_cos);
913 r = mpf1(t, mpfr_sin);
918 int mpsincosl(struct t *t)
922 r = mpl1(t, mpfr_cos);
928 r = mpl1(t, mpfr_sin);
933 int mpremquo(struct t *t) { return mpd2(t, wrap_remquo) || (t->i = mpremquo_q, 0); }
934 int mpremquof(struct t *t) { return mpf2(t, wrap_remquo) || (t->i = mpremquo_q, 0); }
935 int mpremquol(struct t *t) { return mpl2(t, wrap_remquo) || (t->i = mpremquo_q, 0); }
937 int mpfma(struct t *t)
941 MPFR_DECL_INIT(mx, 53);
942 MPFR_DECL_INIT(mx2, 53);
943 MPFR_DECL_INIT(mx3, 53);
944 MPFR_DECL_INIT(my, 128);
948 mpfr_set_d(mx, t->x, MPFR_RNDN);
949 mpfr_set_d(mx2, t->x2, MPFR_RNDN);
950 mpfr_set_d(mx3, t->x3, MPFR_RNDN);
951 tn = mpfr_fma(my, mx, mx2, mx3, r);
953 if ((t->e & INEXACT) && nextafter(t->y, 0) == 0) {
954 mpfr_set_emin(-(1<<20));
955 tn = mpfr_fma(my, mx, mx2, mx3, r);
956 mpfr_mul_2si(my, my, 1074, MPFR_RNDN);
957 t->dy = scalbnl(t->y, 1074) - mpfr_get_ld(my, r);
958 mpfr_set_emin(-1073);
963 int mpfmaf(struct t *t)
967 MPFR_DECL_INIT(mx, 24);
968 MPFR_DECL_INIT(mx2, 24);
969 MPFR_DECL_INIT(mx3, 24);
970 MPFR_DECL_INIT(my, 128);
974 mpfr_set_flt(mx, t->x, MPFR_RNDN);
975 mpfr_set_flt(mx2, t->x2, MPFR_RNDN);
976 mpfr_set_flt(mx3, t->x3, MPFR_RNDN);
977 tn = mpfr_fma(my, mx, mx2, mx3, r);
979 if ((t->e & INEXACT) && nextafterf(t->y, 0) == 0) {
980 mpfr_set_emin(-(1<<20));
981 tn = mpfr_fma(my, mx, mx2, mx3, r);
982 mpfr_mul_2si(my, my, 149, MPFR_RNDN);
983 t->dy = scalbnl(t->y, 149) - mpfr_get_ld(my, r);
989 int mpfmal(struct t *t)
991 #if LDBL_MANT_DIG == 53
993 #elif LDBL_MANT_DIG == 64
996 MPFR_DECL_INIT(mx, 64);
997 MPFR_DECL_INIT(mx2, 64);
998 MPFR_DECL_INIT(mx3, 64);
999 MPFR_DECL_INIT(my, 128);
1003 mpfr_set_ld(mx, t->x, MPFR_RNDN);
1004 mpfr_set_ld(mx2, t->x2, MPFR_RNDN);
1005 mpfr_set_ld(mx3, t->x3, MPFR_RNDN);
1006 tn = mpfr_fma(my, mx, mx2, mx3, r);
1008 if ((t->e & INEXACT) && nextafterl(t->y, 0) == 0) {
1009 mpfr_set_emin(-(1<<20));
1010 tn = mpfr_fma(my, mx, mx2, mx3, r);
1011 mpfr_mul_2si(my, my, 16445, MPFR_RNDN);
1012 t->dy = scalbnl(t->y, 16445) - mpfr_get_ld(my, r);
1013 mpfr_set_emin(-16444);
1021 int mpjn(struct t *t) { mpbessel_n = t->i; return mpd1(t, wrap_jn); }
1022 int mpjnf(struct t *t) { mpbessel_n = t->i; return mpf1(t, wrap_jn); }
1023 int mpjnl(struct t *t) { mpbessel_n = t->i; return mpl1(t, wrap_jn); }
1024 int mpyn(struct t *t) { mpbessel_n = t->i; return mpd1(t, wrap_yn); }
1025 int mpynf(struct t *t) { mpbessel_n = t->i; return mpf1(t, wrap_yn); }
1026 int mpynl(struct t *t) { mpbessel_n = t->i; return mpl1(t, wrap_yn); }