Blame src/math/gen/mp.c

nsz f9d179
#include <stdio.h>
nsz f9d179
nsz f9d179
#include <stdint.h>
nsz f9d179
#include <mpfr.h>
nsz f9d179
#include "gen.h"
nsz f9d179
nsz f9d179
static int rmap(int r)
nsz f9d179
{
nsz f9d179
	switch (r) {
nsz f9d179
	case RN: return MPFR_RNDN;
nsz f9d179
	case RZ: return MPFR_RNDZ;
nsz f9d179
	case RD: return MPFR_RNDD;
nsz f9d179
	case RU: return MPFR_RNDU;
nsz f9d179
	}
nsz f9d179
	return -1;
nsz f9d179
}
nsz f9d179
nsz f9d179
void debug(mpfr_t x)
nsz f9d179
{
nsz f9d179
	mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
nsz f9d179
	printf("\n");
nsz f9d179
}
nsz f9d179
nsz f9d179
void mpsetup()
nsz f9d179
{
nsz f9d179
	mpfr_set_emin(-1073);
nsz f9d179
	mpfr_set_emax(1024);
nsz f9d179
}
nsz f9d179
void mpsetupf()
nsz f9d179
{
nsz f9d179
	mpfr_set_emin(-148);
nsz f9d179
	mpfr_set_emax(128);
nsz f9d179
}
nsz f9d179
#if LDBL_MANT_DIG == 64
nsz f9d179
void mpsetupl()
nsz f9d179
{
nsz f9d179
	mpfr_set_emin(-16444);
nsz f9d179
	mpfr_set_emax(16384);
nsz f9d179
}
nsz f9d179
#endif
nsz f9d179
nsz f9d179
/*
nsz f9d179
round x into y considering x is already rounded (t = up or down)
nsz f9d179
nsz f9d179
only cases where adjustment is done:
nsz f9d179
	x=...|1...0, t=up    -> x=nextbelow(x)
nsz f9d179
	x=...|1...0, t=down  -> x=nextabove(x)
nsz f9d179
where | is the rounding point, ... is 0 or 1 bit patterns
nsz f9d179
*/
nsz f9d179
nsz f9d179
// TODO: adjust(y, 0, 2, RN); when prec is 24 (0 vs 0x1p-149f), special case x=0
nsz f9d179
static int adjust_round(mpfr_t y, mpfr_t x, int t, int r)
nsz f9d179
{
nsz f9d179
	mp_limb_t *p, *q;
nsz f9d179
	unsigned xp, yp;
nsz f9d179
	int t2;
nsz f9d179
nsz f9d179
	xp = mpfr_get_prec(x);
nsz f9d179
	yp = mpfr_get_prec(y);
nsz f9d179
	if (yp >= xp || r != MPFR_RNDN || t == 0 || !mpfr_number_p(x) || mpfr_zero_p(x)) {
nsz f9d179
		t2 = mpfr_set(y, x, r);
nsz f9d179
		return t2 ? t2 : t;
nsz f9d179
	}
nsz f9d179
	p = x->_mpfr_d;
nsz f9d179
	yp++;
nsz f9d179
	q = p + (xp + mp_bits_per_limb - 1)/mp_bits_per_limb - (yp + mp_bits_per_limb - 1)/mp_bits_per_limb;
nsz f9d179
	if ((*p & 1 << -xp%mp_bits_per_limb) || !(*q & 1 << -yp%mp_bits_per_limb)) {
nsz f9d179
		t2 = mpfr_set(y, x, r);
nsz f9d179
		return t2 ? t2 : t;
nsz f9d179
	}
nsz f9d179
	if (t > 0)
nsz f9d179
		mpfr_nextbelow(x);
nsz f9d179
	else
nsz f9d179
		mpfr_nextabove(x);
nsz f9d179
	return mpfr_set(y, x, r);
nsz f9d179
}
nsz f9d179
nsz f9d179
static int adjust(mpfr_t mr, mpfr_t my, int t, int r)
nsz f9d179
{
nsz f9d179
//	double d, dn, dp;
nsz f9d179
//printf("adj %d\n", t);
nsz f9d179
//debug(my);
nsz f9d179
	t = adjust_round(mr, my, t, r);
nsz f9d179
//printf("rnd %d\n", t);
nsz f9d179
//debug(mr);
nsz f9d179
	t = mpfr_subnormalize(mr, t, r);
nsz f9d179
//printf("sub %d\n", t);
nsz f9d179
//debug(mr);
nsz f9d179
//	d = mpfr_get_d(mr, r);
nsz f9d179
//	dn = nextafter(d, INFINITY);
nsz f9d179
//	dp = nextafter(d, -INFINITY);
nsz f9d179
//printf("c\n %.21e %a\n %.21e %a\n %.21e %a\n",d,d,dn,dn,dp,dp);
nsz f9d179
//	dn = nextafterf(d, INFINITY);
nsz f9d179
//	dp = nextafterf(d, -INFINITY);
nsz f9d179
//printf("cf\n %.21e %a\n %.21e %a\n %.21e %a\n",d,d,dn,dn,dp,dp);
nsz f9d179
	return t;
nsz f9d179
}
nsz f9d179
nsz f9d179
// TODO
nsz f9d179
//static int eflags(mpfr_t mr, mpfr_t my, int t)
nsz f9d179
static int eflags(int naninput)
nsz f9d179
{
nsz f9d179
	int i = 0;
nsz f9d179
nsz f9d179
	if (mpfr_inexflag_p())
nsz f9d179
		i |= FE_INEXACT;
nsz f9d179
//	if (mpfr_underflow_p() && (t || mpfr_cmp(mr, my) != 0))
nsz f9d179
	if (mpfr_underflow_p() && i)
nsz f9d179
		i |= FE_UNDERFLOW;
nsz f9d179
	if (mpfr_overflow_p())
nsz f9d179
		i |= FE_OVERFLOW;
nsz f9d179
	if (mpfr_divby0_p())
nsz f9d179
		i |= FE_DIVBYZERO;
nsz f9d179
	if (!naninput && (mpfr_nanflag_p() || mpfr_erangeflag_p()))
nsz f9d179
		i |= FE_INVALID;
nsz f9d179
	return i;
nsz f9d179
}
nsz f9d179
nsz f9d179
static void genf(struct t *p, mpfr_t my, int t, int r)
nsz f9d179
{
nsz f9d179
	MPFR_DECL_INIT(mr, 24);
nsz f9d179
	int i;
nsz f9d179
nsz f9d179
	t = adjust(mr, my, t, r);
nsz f9d179
	p->y = mpfr_get_flt(mr, r);
nsz f9d179
	p->e = eflags(isnan(p->x) || isnan(p->x2));
nsz f9d179
	i = eulpf(p->y);
nsz f9d179
	if (!isfinite(p->y)) {
nsz f9d179
		p->dy = 0;
nsz f9d179
	} else if (i < 0) {
nsz f9d179
		mpfr_div_2si(mr, mr, i, MPFR_RNDN);
nsz f9d179
		mpfr_div_2si(my, my, i, MPFR_RNDN);
nsz f9d179
		mpfr_sub(my, mr, my, MPFR_RNDN);
nsz f9d179
		p->dy = mpfr_get_flt(my, r);
nsz f9d179
	} else {
nsz f9d179
		mpfr_sub(my, mr, my, MPFR_RNDN);
nsz f9d179
		mpfr_div_2si(my, my, i, MPFR_RNDN);
nsz f9d179
		p->dy = mpfr_get_flt(my, r);
nsz f9d179
	}
nsz f9d179
}
nsz f9d179
nsz f9d179
static int mpf1(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, mpfr_rnd_t))
nsz f9d179
{
nsz f9d179
	int tn;
nsz f9d179
	int r = rmap(p->r);
nsz f9d179
	MPFR_DECL_INIT(mx, 24);
nsz f9d179
	MPFR_DECL_INIT(my, 128);
nsz f9d179
nsz f9d179
	mpsetupf();
nsz f9d179
	mpfr_clear_flags();
nsz f9d179
	mpfr_set_flt(mx, p->x, MPFR_RNDN);
nsz f9d179
	tn = fmp(my, mx, r);
nsz f9d179
	p->x2 = 0;
nsz f9d179
	genf(p, my, tn, r);
nsz f9d179
	if ((p->e & INEXACT) && nextafterf(p->y, 0) == 0) {
nsz f9d179
		mpfr_set_emin(-(1<<20));
nsz f9d179
		tn = fmp(my, mx, r);
nsz f9d179
		mpfr_mul_2si(my, my, 149, MPFR_RNDN);
nsz f9d179
		p->dy = scalbnl(p->y, 149) - mpfr_get_ld(my, r);
nsz f9d179
		mpfr_set_emin(-148);
nsz f9d179
	}
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
nsz f9d179
static int mpf2(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t))
nsz f9d179
{
nsz f9d179
	int tn;
nsz f9d179
	int r = rmap(p->r);
nsz f9d179
	MPFR_DECL_INIT(mx, 24);
nsz f9d179
	MPFR_DECL_INIT(mx2, 24);
nsz f9d179
	MPFR_DECL_INIT(my, 128);
nsz f9d179
nsz f9d179
	mpsetupf();
nsz f9d179
	mpfr_clear_flags();
nsz f9d179
	mpfr_set_flt(mx, p->x, MPFR_RNDN);
nsz f9d179
	mpfr_set_flt(mx2, p->x2, MPFR_RNDN);
nsz f9d179
	tn = fmp(my, mx, mx2, r);
nsz f9d179
	genf(p, my, tn, r);
nsz f9d179
	if ((p->e & INEXACT) && nextafterf(p->y, 0) == 0) {
nsz f9d179
		mpfr_set_emin(-(1<<20));
nsz f9d179
		tn = fmp(my, mx, mx2, r);
nsz f9d179
		mpfr_mul_2si(my, my, 149, MPFR_RNDN);
nsz f9d179
		p->dy = scalbnl(p->y, 149) - mpfr_get_ld(my, r);
nsz f9d179
		mpfr_set_emin(-148);
nsz f9d179
	}
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
nsz f9d179
static void gend(struct t *p, mpfr_t my, int t, int r)
nsz f9d179
{
nsz f9d179
	MPFR_DECL_INIT(mr, 53);
nsz f9d179
	int i;
nsz f9d179
nsz f9d179
	t = adjust(mr, my, t, r);
nsz f9d179
	p->y = mpfr_get_d(mr, r);
nsz f9d179
	p->e = eflags(isnan(p->x) || isnan(p->x2));
nsz f9d179
	i = eulp(p->y);
nsz f9d179
	if (!isfinite(p->y)) {
nsz f9d179
		p->dy = 0;
nsz f9d179
	} else if (i < 0) {
nsz f9d179
		mpfr_div_2si(mr, mr, i, MPFR_RNDN);
nsz f9d179
		mpfr_div_2si(my, my, i, MPFR_RNDN);
nsz f9d179
		mpfr_sub(my, mr, my, MPFR_RNDN);
nsz f9d179
		p->dy = mpfr_get_flt(my, r);
nsz f9d179
	} else {
nsz f9d179
		mpfr_sub(my, mr, my, MPFR_RNDN);
nsz f9d179
		mpfr_div_2si(my, my, i, MPFR_RNDN);
nsz f9d179
		p->dy = mpfr_get_flt(my, r);
nsz f9d179
	}
nsz f9d179
}
nsz f9d179
nsz f9d179
static int mpd1(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, mpfr_rnd_t))
nsz f9d179
{
nsz f9d179
	int tn;
nsz f9d179
	int r = rmap(p->r);
nsz f9d179
	MPFR_DECL_INIT(mx, 53);
nsz f9d179
	MPFR_DECL_INIT(my, 128);
nsz f9d179
nsz f9d179
	mpsetup();
nsz f9d179
	mpfr_clear_flags();
nsz f9d179
	mpfr_set_d(mx, p->x, MPFR_RNDN);
nsz f9d179
	tn = fmp(my, mx, r);
nsz f9d179
//printf("underflow: %d\n", mpfr_underflow_p());
nsz f9d179
	p->x2 = 0;
nsz f9d179
	gend(p, my, tn, r);
nsz f9d179
//printf("dy: %a  %.3f\n", p->dy, p->dy);
nsz f9d179
	if ((p->e & INEXACT) && nextafter(p->y, 0) == 0) {
nsz f9d179
		mpfr_set_emin(-(1<<20));
nsz f9d179
		tn = fmp(my, mx, r);
nsz f9d179
		mpfr_mul_2si(my, my, 1074, MPFR_RNDN);
nsz f9d179
//debug(my);
nsz f9d179
		p->dy = scalbnl(p->y, 1074) - mpfr_get_ld(my, r);
nsz f9d179
//printf("dy: %a  %.3f\n", p->dy, p->dy);
nsz f9d179
		mpfr_set_emin(-1073);
nsz f9d179
	}
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
nsz f9d179
static int mpd2(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t))
nsz f9d179
{
nsz f9d179
	int tn;
nsz f9d179
	int r = rmap(p->r);
nsz f9d179
	MPFR_DECL_INIT(mx, 53);
nsz f9d179
	MPFR_DECL_INIT(mx2, 53);
nsz f9d179
	MPFR_DECL_INIT(my, 128);
nsz f9d179
nsz f9d179
	mpsetup();
nsz f9d179
	mpfr_clear_flags();
nsz f9d179
	mpfr_set_d(mx, p->x, MPFR_RNDN);
nsz f9d179
	mpfr_set_d(mx2, p->x2, MPFR_RNDN);
nsz f9d179
	tn = fmp(my, mx, mx2, r);
nsz f9d179
	gend(p, my, tn, r);
nsz f9d179
	if ((p->e & INEXACT) && nextafter(p->y, 0) == 0) {
nsz f9d179
		mpfr_set_emin(-(1<<20));
nsz f9d179
		tn = fmp(my, mx, mx2, r);
nsz f9d179
		mpfr_mul_2si(my, my, 1074, MPFR_RNDN);
nsz f9d179
		p->dy = scalbnl(p->y, 1074) - mpfr_get_ld(my, r);
nsz f9d179
		mpfr_set_emin(-1073);
nsz f9d179
	}
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
nsz f9d179
#if LDBL_MANT_DIG == 64
nsz f9d179
static void genl(struct t *p, mpfr_t my, int t, int r)
nsz f9d179
{
nsz f9d179
	MPFR_DECL_INIT(mr, 64);
nsz f9d179
	int i;
nsz f9d179
nsz f9d179
	t = adjust(mr, my, t, r);
nsz f9d179
	p->y = mpfr_get_ld(mr, r);
nsz f9d179
	p->e = eflags(isnan(p->x) || isnan(p->x2));
nsz f9d179
	i = eulpl(p->y);
nsz f9d179
	if (!isfinite(p->y)) {
nsz f9d179
		p->dy = 0;
nsz f9d179
	} else if (i < 0) {
nsz f9d179
		mpfr_div_2si(mr, mr, i, MPFR_RNDN);
nsz f9d179
		mpfr_div_2si(my, my, i, MPFR_RNDN);
nsz f9d179
		mpfr_sub(my, mr, my, MPFR_RNDN);
nsz f9d179
		p->dy = mpfr_get_flt(my, r);
nsz f9d179
	} else {
nsz f9d179
		mpfr_sub(my, mr, my, MPFR_RNDN);
nsz f9d179
		mpfr_div_2si(my, my, i, MPFR_RNDN);
nsz f9d179
		p->dy = mpfr_get_flt(my, r);
nsz f9d179
	}
nsz f9d179
}
nsz f9d179
#endif
nsz f9d179
nsz f9d179
static int mpl1(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, mpfr_rnd_t))
nsz f9d179
{
nsz f9d179
#if LDBL_MANT_DIG == 53
nsz f9d179
	return mpd1(p, fmp);
nsz f9d179
#elif LDBL_MANT_DIG == 64
nsz f9d179
	int tn;
nsz f9d179
	int r = rmap(p->r);
nsz f9d179
	MPFR_DECL_INIT(mx, 64);
nsz f9d179
	MPFR_DECL_INIT(my, 128);
nsz f9d179
nsz f9d179
	mpsetupl();
nsz f9d179
	mpfr_clear_flags();
nsz f9d179
	mpfr_set_ld(mx, p->x, MPFR_RNDN);
nsz f9d179
	tn = fmp(my, mx, r);
nsz f9d179
	p->x2 = 0;
nsz f9d179
	genl(p, my, tn, r);
nsz f9d179
	if ((p->e & INEXACT) && nextafterl(p->y, 0) == 0) {
nsz f9d179
		mpfr_set_emin(-(1<<20));
nsz f9d179
		tn = fmp(my, mx, r);
nsz f9d179
		mpfr_mul_2si(my, my, 16445, MPFR_RNDN);
nsz f9d179
		p->dy = scalbnl(p->y, 16445) - mpfr_get_ld(my, r);
nsz f9d179
		mpfr_set_emin(-16444);
nsz f9d179
	}
nsz f9d179
	return 0;
nsz f9d179
#else
nsz f9d179
	return -1;
nsz f9d179
#endif
nsz f9d179
}
nsz f9d179
nsz f9d179
static int mpl2(struct t *p, int (*fmp)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t))
nsz f9d179
{
nsz f9d179
#if LDBL_MANT_DIG == 53
nsz f9d179
	return mpd2(p, fmp);
nsz f9d179
#elif LDBL_MANT_DIG == 64
nsz f9d179
	int tn;
nsz f9d179
	int r = rmap(p->r);
nsz f9d179
	MPFR_DECL_INIT(mx, 64);
nsz f9d179
	MPFR_DECL_INIT(mx2, 64);
nsz f9d179
	MPFR_DECL_INIT(my, 128);
nsz f9d179
nsz f9d179
	mpsetupl();
nsz f9d179
	mpfr_clear_flags();
nsz 79ae5f
	mpfr_set_ld(mx, p->x, MPFR_RNDN);
nsz 79ae5f
	mpfr_set_ld(mx2, p->x2, MPFR_RNDN);
nsz f9d179
	tn = fmp(my, mx, mx2, r);
nsz f9d179
	genl(p, my, tn, r);
nsz f9d179
	if ((p->e & INEXACT) && nextafterl(p->y, 0) == 0) {
nsz f9d179
		mpfr_set_emin(-(1<<20));
nsz f9d179
		tn = fmp(my, mx, mx2, r);
nsz f9d179
		mpfr_mul_2si(my, my, 16445, MPFR_RNDN);
nsz f9d179
		p->dy = scalbnl(p->y, 16445) - mpfr_get_ld(my, r);
nsz f9d179
		mpfr_set_emin(-16444);
nsz f9d179
	}
nsz f9d179
	return 0;
nsz f9d179
#else
nsz f9d179
	return -1;
nsz f9d179
#endif
nsz f9d179
}
nsz f9d179
nsz f9d179
// TODO
nsz f9d179
static int mplgamma_sign;
nsz f9d179
static int wrap_lgamma(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
nsz f9d179
{
nsz f9d179
	return mpfr_lgamma(my, &mplgamma_sign, mx, r);
nsz f9d179
}
nsz f9d179
static int wrap_ceil(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
nsz f9d179
{
nsz f9d179
	return mpfr_ceil(my, mx);
nsz f9d179
}
nsz f9d179
static int wrap_floor(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
nsz f9d179
{
nsz f9d179
	return mpfr_floor(my, mx);
nsz f9d179
}
nsz f9d179
static int wrap_round(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
nsz f9d179
{
nsz f9d179
	return mpfr_round(my, mx);
nsz f9d179
}
nsz f9d179
static int wrap_trunc(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
nsz f9d179
{
nsz f9d179
	return mpfr_trunc(my, mx);
nsz f9d179
}
nsz f9d179
static int wrap_nearbyint(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
nsz f9d179
{
nsz f9d179
	int i = mpfr_rint(my, mx, r);
nsz f9d179
	mpfr_clear_inexflag();
nsz f9d179
	return i;
nsz f9d179
}
nsz f9d179
static int wrap_pow10(mpfr_t my, const mpfr_t mx, mpfr_rnd_t r)
nsz f9d179
{
nsz f9d179
	return mpfr_ui_pow(my, 10, mx, r);
nsz f9d179
}
nsz f9d179
nsz f9d179
int mpacos(struct t *t) { return mpd1(t, mpfr_acos); }
nsz f9d179
int mpacosf(struct t *t) { return mpf1(t, mpfr_acos); }
nsz f9d179
int mpacosl(struct t *t) { return mpl1(t, mpfr_acos); }
nsz f9d179
int mpacosh(struct t *t) { return mpd1(t, mpfr_acosh); }
nsz f9d179
int mpacoshf(struct t *t) { return mpf1(t, mpfr_acosh); }
nsz f9d179
int mpacoshl(struct t *t) { return mpl1(t, mpfr_acosh); }
nsz f9d179
int mpasin(struct t *t) { return mpd1(t, mpfr_asin); }
nsz f9d179
int mpasinf(struct t *t) { return mpf1(t, mpfr_asin); }
nsz f9d179
int mpasinl(struct t *t) { return mpl1(t, mpfr_asin); }
nsz f9d179
int mpasinh(struct t *t) { return mpd1(t, mpfr_asinh); }
nsz f9d179
int mpasinhf(struct t *t) { return mpf1(t, mpfr_asinh); }
nsz f9d179
int mpasinhl(struct t *t) { return mpl1(t, mpfr_asinh); }
nsz f9d179
int mpatan(struct t *t) { return mpd1(t, mpfr_atan); }
nsz f9d179
int mpatanf(struct t *t) { return mpf1(t, mpfr_atan); }
nsz f9d179
int mpatanl(struct t *t) { return mpl1(t, mpfr_atan); }
nsz f9d179
int mpatan2(struct t *t) { return mpd2(t, mpfr_atan2); }
nsz f9d179
int mpatan2f(struct t *t) { return mpf2(t, mpfr_atan2); }
nsz f9d179
int mpatan2l(struct t *t) { return mpl2(t, mpfr_atan2); }
nsz f9d179
int mpatanh(struct t *t) { return mpd1(t, mpfr_atanh); }
nsz f9d179
int mpatanhf(struct t *t) { return mpf1(t, mpfr_atanh); }
nsz f9d179
int mpatanhl(struct t *t) { return mpl1(t, mpfr_atanh); }
nsz f9d179
int mpcbrt(struct t *t) { return mpd1(t, mpfr_cbrt); }
nsz f9d179
int mpcbrtf(struct t *t) { return mpf1(t, mpfr_cbrt); }
nsz f9d179
int mpcbrtl(struct t *t) { return mpl1(t, mpfr_cbrt); }
nsz f9d179
int mpceil(struct t *t) { return mpd1(t, wrap_ceil); }
nsz f9d179
int mpceilf(struct t *t) { return mpf1(t, wrap_ceil); }
nsz f9d179
int mpceill(struct t *t) { return mpl1(t, wrap_ceil); }
nsz f9d179
int mpcopysign(struct t *t) { return mpd2(t, mpfr_copysign); }
nsz f9d179
int mpcopysignf(struct t *t) { return mpf2(t, mpfr_copysign); }
nsz f9d179
int mpcopysignl(struct t *t) { return mpl2(t, mpfr_copysign); }
nsz f9d179
int mpcos(struct t *t) { return mpd1(t, mpfr_cos); }
nsz f9d179
int mpcosf(struct t *t) { return mpf1(t, mpfr_cos); }
nsz f9d179
int mpcosl(struct t *t) { return mpl1(t, mpfr_cos); }
nsz f9d179
int mpcosh(struct t *t) { return mpd1(t, mpfr_cosh); }
nsz f9d179
int mpcoshf(struct t *t) { return mpf1(t, mpfr_cosh); }
nsz f9d179
int mpcoshl(struct t *t) { return mpl1(t, mpfr_cosh); }
nsz f9d179
int mperf(struct t *t) { return mpd1(t, mpfr_erf); }
nsz f9d179
int mperff(struct t *t) { return mpf1(t, mpfr_erf); }
nsz f9d179
int mperfl(struct t *t) { return mpl1(t, mpfr_erf); }
nsz f9d179
int mperfc(struct t *t) { return mpd1(t, mpfr_erfc); }
nsz f9d179
int mperfcf(struct t *t) { return mpf1(t, mpfr_erfc); }
nsz f9d179
int mperfcl(struct t *t) { return mpl1(t, mpfr_erfc); }
nsz f9d179
int mpexp(struct t *t) { return mpd1(t, mpfr_exp); }
nsz f9d179
int mpexpf(struct t *t) { return mpf1(t, mpfr_exp); }
nsz f9d179
int mpexpl(struct t *t) { return mpl1(t, mpfr_exp); }
nsz f9d179
int mpexp2(struct t *t) { return mpd1(t, mpfr_exp2); }
nsz f9d179
int mpexp2f(struct t *t) { return mpf1(t, mpfr_exp2); }
nsz f9d179
int mpexp2l(struct t *t) { return mpl1(t, mpfr_exp2); }
nsz f9d179
int mpexpm1(struct t *t) { return mpd1(t, mpfr_expm1); }
nsz f9d179
int mpexpm1f(struct t *t) { return mpf1(t, mpfr_expm1); }
nsz f9d179
int mpexpm1l(struct t *t) { return mpl1(t, mpfr_expm1); }
nsz f9d179
int mpfabs(struct t *t) { return mpd1(t, mpfr_abs); }
nsz f9d179
int mpfabsf(struct t *t) { return mpf1(t, mpfr_abs); }
nsz f9d179
int mpfabsl(struct t *t) { return mpl1(t, mpfr_abs); }
nsz f9d179
int mpfdim(struct t *t) { return mpd2(t, mpfr_dim); }
nsz f9d179
int mpfdimf(struct t *t) { return mpf2(t, mpfr_dim); }
nsz f9d179
int mpfdiml(struct t *t) { return mpl2(t, mpfr_dim); }
nsz f9d179
int mpfloor(struct t *t) { return mpd1(t, wrap_floor); }
nsz f9d179
int mpfloorf(struct t *t) { return mpf1(t, wrap_floor); }
nsz f9d179
int mpfloorl(struct t *t) { return mpl1(t, wrap_floor); }
nsz f9d179
int mpfmax(struct t *t) { return mpd2(t, mpfr_max); }
nsz f9d179
int mpfmaxf(struct t *t) { return mpf2(t, mpfr_max); }
nsz f9d179
int mpfmaxl(struct t *t) { return mpl2(t, mpfr_max); }
nsz f9d179
int mpfmin(struct t *t) { return mpd2(t, mpfr_min); }
nsz f9d179
int mpfminf(struct t *t) { return mpf2(t, mpfr_min); }
nsz f9d179
int mpfminl(struct t *t) { return mpl2(t, mpfr_min); }
nsz f9d179
int mpfmod(struct t *t) { return mpd2(t, mpfr_fmod); }
nsz f9d179
int mpfmodf(struct t *t) { return mpf2(t, mpfr_fmod); }
nsz f9d179
int mpfmodl(struct t *t) { return mpl2(t, mpfr_fmod); }
nsz f9d179
int mphypot(struct t *t) { return mpd2(t, mpfr_hypot); }
nsz f9d179
int mphypotf(struct t *t) { return mpf2(t, mpfr_hypot); }
nsz f9d179
int mphypotl(struct t *t) { return mpl2(t, mpfr_hypot); }
nsz f9d179
int mplgamma(struct t *t) { return mpd1(t, wrap_lgamma) || (t->i = mplgamma_sign, 0); }
nsz f9d179
int mplgammaf(struct t *t) { return mpf1(t, wrap_lgamma) || (t->i = mplgamma_sign, 0); }
nsz f9d179
int mplgammal(struct t *t) { return mpl1(t, wrap_lgamma) || (t->i = mplgamma_sign, 0); }
nsz f9d179
int mplog(struct t *t) { return mpd1(t, mpfr_log); }
nsz f9d179
int mplogf(struct t *t) { return mpf1(t, mpfr_log); }
nsz f9d179
int mplogl(struct t *t) { return mpl1(t, mpfr_log); }
nsz f9d179
int mplog10(struct t *t) { return mpd1(t, mpfr_log10); }
nsz f9d179
int mplog10f(struct t *t) { return mpf1(t, mpfr_log10); }
nsz f9d179
int mplog10l(struct t *t) { return mpl1(t, mpfr_log10); }
nsz f9d179
int mplog1p(struct t *t) { return mpd1(t, mpfr_log1p); }
nsz f9d179
int mplog1pf(struct t *t) { return mpf1(t, mpfr_log1p); }
nsz f9d179
int mplog1pl(struct t *t) { return mpl1(t, mpfr_log1p); }
nsz f9d179
int mplog2(struct t *t) { return mpd1(t, mpfr_log2); }
nsz f9d179
int mplog2f(struct t *t) { return mpf1(t, mpfr_log2); }
nsz f9d179
int mplog2l(struct t *t) { return mpl1(t, mpfr_log2); }
nsz f9d179
int mplogb(struct t *t)
nsz f9d179
{
nsz f9d179
	MPFR_DECL_INIT(mx, 53);
nsz f9d179
nsz f9d179
	mpfr_set_d(mx, t->x, MPFR_RNDN);
nsz 8d3db4
	t->y = mpfr_get_exp(mx) - 1;
nsz f9d179
	t->dy = 0;
nsz f9d179
	t->e = 0;
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
int mplogbf(struct t *t)
nsz f9d179
{
nsz f9d179
	MPFR_DECL_INIT(mx, 24);
nsz f9d179
nsz f9d179
	mpfr_set_flt(mx, t->x, MPFR_RNDN);
nsz 8d3db4
	t->y = mpfr_get_exp(mx) - 1;
nsz f9d179
	t->dy = 0;
nsz f9d179
	t->e = 0;
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
int mplogbl(struct t *t)
nsz f9d179
{
nsz f9d179
	MPFR_DECL_INIT(mx, 64);
nsz f9d179
nsz f9d179
	mpfr_set_ld(mx, t->x, MPFR_RNDN);
nsz 8d3db4
	t->y = mpfr_get_exp(mx) - 1;
nsz f9d179
	t->dy = 0;
nsz f9d179
	t->e = 0;
nsz f9d179
	return 0;
nsz f9d179
}
nsz 457b0d
int mpnearbyint(struct t *t) { return mpd1(t, wrap_nearbyint) || (t->e&=~INEXACT, 0); }
nsz 457b0d
int mpnearbyintf(struct t *t) { return mpf1(t, wrap_nearbyint) || (t->e&=~INEXACT, 0); }
nsz 457b0d
int mpnearbyintl(struct t *t) { return mpl1(t, wrap_nearbyint) || (t->e&=~INEXACT, 0); }
nsz f9d179
int mpnextafter(struct t *t) { return -1; }
nsz f9d179
int mpnextafterf(struct t *t) { return -1; }
nsz f9d179
int mpnextafterl(struct t *t) { return -1; }
nsz f9d179
int mpnexttowardl(struct t *t) { return -1; }
nsz f9d179
int mppow(struct t *t) { return mpd2(t, mpfr_pow); }
nsz f9d179
int mppowf(struct t *t) { return mpf2(t, mpfr_pow); }
nsz f9d179
int mppowl(struct t *t) { return mpl2(t, mpfr_pow); }
nsz f9d179
int mpremainder(struct t *t) { return mpd2(t, mpfr_remainder); }
nsz f9d179
int mpremainderf(struct t *t) { return mpf2(t, mpfr_remainder); }
nsz f9d179
int mpremainderl(struct t *t) { return mpl2(t, mpfr_remainder); }
nsz f9d179
int mprint(struct t *t) { return mpd1(t, mpfr_rint); }
nsz f9d179
int mprintf(struct t *t) { return mpf1(t, mpfr_rint); }
nsz f9d179
int mprintl(struct t *t) { return mpl1(t, mpfr_rint); }
nsz f9d179
int mpround(struct t *t) { return mpd1(t, wrap_round); }
nsz f9d179
int mproundf(struct t *t) { return mpf1(t, wrap_round); }
nsz f9d179
int mproundl(struct t *t) { return mpl1(t, wrap_round); }
nsz f9d179
int mpsin(struct t *t) { return mpd1(t, mpfr_sin); }
nsz f9d179
int mpsinf(struct t *t) { return mpf1(t, mpfr_sin); }
nsz f9d179
int mpsinl(struct t *t) { return mpl1(t, mpfr_sin); }
nsz f9d179
int mpsinh(struct t *t) { return mpd1(t, mpfr_sinh); }
nsz f9d179
int mpsinhf(struct t *t) { return mpf1(t, mpfr_sinh); }
nsz f9d179
int mpsinhl(struct t *t) { return mpl1(t, mpfr_sinh); }
nsz f9d179
int mpsqrt(struct t *t) { return mpd1(t, mpfr_sqrt); }
nsz f9d179
int mpsqrtf(struct t *t) { return mpf1(t, mpfr_sqrt); }
nsz f9d179
int mpsqrtl(struct t *t) { return mpl1(t, mpfr_sqrt); }
nsz f9d179
int mptan(struct t *t) { return mpd1(t, mpfr_tan); }
nsz f9d179
int mptanf(struct t *t) { return mpf1(t, mpfr_tan); }
nsz f9d179
int mptanl(struct t *t) { return mpl1(t, mpfr_tan); }
nsz f9d179
int mptanh(struct t *t) { return mpd1(t, mpfr_tanh); }
nsz f9d179
int mptanhf(struct t *t) { return mpf1(t, mpfr_tanh); }
nsz f9d179
int mptanhl(struct t *t) { return mpl1(t, mpfr_tanh); }
nsz f9d179
int mptgamma(struct t *t) { return mpd1(t, mpfr_gamma); }
nsz f9d179
int mptgammaf(struct t *t) { return mpf1(t, mpfr_gamma); }
nsz f9d179
int mptgammal(struct t *t) { return mpl1(t, mpfr_gamma); }
nsz f9d179
int mptrunc(struct t *t) { return mpd1(t, wrap_trunc); }
nsz f9d179
int mptruncf(struct t *t) { return mpf1(t, wrap_trunc); }
nsz f9d179
int mptruncl(struct t *t) { return mpl1(t, wrap_trunc); }
nsz f9d179
int mpj0(struct t *t) { return mpd1(t, mpfr_j0); }
nsz f9d179
int mpj1(struct t *t) { return mpd1(t, mpfr_j1); }
nsz f9d179
int mpy0(struct t *t) { return mpd1(t, mpfr_y0); }
nsz f9d179
int mpy1(struct t *t) { return mpd1(t, mpfr_y1); }
nsz f9d179
int mpscalb(struct t *t) { return -1; }
nsz f9d179
int mpscalbf(struct t *t) { return -1; }
nsz f9d179
int mpj0f(struct t *t) { return mpf1(t, mpfr_j0); }
nsz f9d179
int mpj0l(struct t *t) { return mpl1(t, mpfr_j0); }
nsz f9d179
int mpj1f(struct t *t) { return mpf1(t, mpfr_j1); }
nsz f9d179
int mpj1l(struct t *t) { return mpl1(t, mpfr_j1); }
nsz f9d179
int mpy0f(struct t *t) { return mpf1(t, mpfr_y0); }
nsz f9d179
int mpy0l(struct t *t) { return mpl1(t, mpfr_y0); }
nsz f9d179
int mpy1f(struct t *t) { return mpf1(t, mpfr_y1); }
nsz f9d179
int mpy1l(struct t *t) { return mpl1(t, mpfr_y1); }
nsz f9d179
int mpexp10(struct t *t) { return mpd1(t, wrap_pow10); }
nsz f9d179
int mpexp10f(struct t *t) { return mpf1(t, wrap_pow10); }
nsz f9d179
int mpexp10l(struct t *t) { return mpl1(t, wrap_pow10); }
nsz f9d179
int mppow10(struct t *t) { return mpd1(t, wrap_pow10); }
nsz f9d179
int mppow10f(struct t *t) { return mpf1(t, wrap_pow10); }
nsz f9d179
int mppow10l(struct t *t) { return mpl1(t, wrap_pow10); }
nsz f9d179
nsz f9d179
int mpfrexp(struct t *t)
nsz f9d179
{
nsz f9d179
	mpfr_exp_t e;
nsz f9d179
	int k;
nsz f9d179
	MPFR_DECL_INIT(mx, 53);
nsz f9d179
nsz f9d179
	t->dy = 0;
nsz f9d179
	t->y = 0;
nsz f9d179
	mpsetup();
nsz f9d179
	mpfr_clear_flags();
nsz f9d179
	mpfr_set_d(mx, t->x, MPFR_RNDN);
nsz f9d179
	k = mpfr_frexp(&e, mx, mx, t->r);
nsz f9d179
	mpfr_subnormalize(mx, k, t->r);
nsz f9d179
	t->y = mpfr_get_d(mx, MPFR_RNDN);
nsz f9d179
	t->i = e;
nsz f9d179
	t->e = eflags(isnan(t->x));
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
nsz f9d179
int mpfrexpf(struct t *t)
nsz f9d179
{
nsz f9d179
	mpfr_exp_t e;
nsz f9d179
	int k;
nsz f9d179
	MPFR_DECL_INIT(mx, 24);
nsz f9d179
nsz f9d179
	t->dy = 0;
nsz f9d179
	t->y = 0;
nsz f9d179
	mpsetup();
nsz f9d179
	mpfr_clear_flags();
nsz f9d179
	mpfr_set_flt(mx, t->x, MPFR_RNDN);
nsz f9d179
	k = mpfr_frexp(&e, mx, mx, t->r);
nsz f9d179
	mpfr_subnormalize(mx, k, t->r);
nsz f9d179
	t->y = mpfr_get_flt(mx, MPFR_RNDN);
nsz f9d179
	t->i = e;
nsz f9d179
	t->e = eflags(isnan(t->x));
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
nsz f9d179
int mpfrexpl(struct t *t)
nsz f9d179
{
nsz f9d179
	mpfr_exp_t e;
nsz f9d179
	int k;
nsz f9d179
	MPFR_DECL_INIT(mx, 64);
nsz f9d179
nsz f9d179
	t->dy = 0;
nsz f9d179
	t->y = 0;
nsz f9d179
	mpsetup();
nsz f9d179
	mpfr_clear_flags();
nsz f9d179
	mpfr_set_ld(mx, t->x, MPFR_RNDN);
nsz f9d179
	k = mpfr_frexp(&e, mx, mx, t->r);
nsz f9d179
	mpfr_subnormalize(mx, k, t->r);
nsz f9d179
	t->y = mpfr_get_ld(mx, MPFR_RNDN);
nsz f9d179
	t->i = e;
nsz f9d179
	t->e = eflags(isnan(t->x));
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
nsz f9d179
int mpldexp(struct t *t)
nsz f9d179
{
nsz f9d179
	int k;
nsz f9d179
	MPFR_DECL_INIT(mx, 53);
nsz f9d179
nsz f9d179
	t->dy = 0;
nsz f9d179
	t->y = 0;
nsz f9d179
	mpsetup();
nsz f9d179
	mpfr_clear_flags();
nsz f9d179
	mpfr_set_d(mx, t->x, MPFR_RNDN);
nsz f9d179
	k = mpfr_mul_2si(mx, mx, t->i, t->r);
nsz f9d179
	mpfr_subnormalize(mx, k, t->r);
nsz f9d179
	t->y = mpfr_get_d(mx, MPFR_RNDN);
nsz f9d179
	t->e = eflags(isnan(t->x));
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
nsz f9d179
int mpldexpf(struct t *t)
nsz f9d179
{
nsz f9d179
	int k;
nsz f9d179
	MPFR_DECL_INIT(mx, 24);
nsz f9d179
nsz f9d179
	t->dy = 0;
nsz f9d179
	t->y = 0;
nsz f9d179
	mpsetup();
nsz f9d179
	mpfr_clear_flags();
nsz f9d179
	mpfr_set_flt(mx, t->x, MPFR_RNDN);
nsz f9d179
	k = mpfr_mul_2si(mx, mx, t->i, t->r);
nsz f9d179
	mpfr_subnormalize(mx, k, t->r);
nsz f9d179
	t->y = mpfr_get_flt(mx, MPFR_RNDN);
nsz f9d179
	t->e = eflags(isnan(t->x));
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
nsz f9d179
int mpldexpl(struct t *t)
nsz f9d179
{
nsz f9d179
	int k;
nsz f9d179
	MPFR_DECL_INIT(mx, 64);
nsz f9d179
nsz f9d179
	t->dy = 0;
nsz f9d179
	t->y = 0;
nsz f9d179
	mpsetup();
nsz f9d179
	mpfr_clear_flags();
nsz f9d179
	mpfr_set_ld(mx, t->x, MPFR_RNDN);
nsz f9d179
	k = mpfr_mul_2si(mx, mx, t->i, t->r);
nsz f9d179
	mpfr_subnormalize(mx, k, t->r);
nsz f9d179
	t->y = mpfr_get_ld(mx, MPFR_RNDN);
nsz f9d179
	t->e = eflags(isnan(t->x));
nsz f9d179
	return 0;
nsz f9d179
}
nsz f9d179
nsz f9d179
int mpscalbn(struct t *t) { return mpldexp(t); }
nsz f9d179
int mpscalbnf(struct t *t) { return mpldexpf(t); }
nsz f9d179
int mpscalbnl(struct t *t) { return mpldexpl(t); }
nsz f9d179
int mpscalbln(struct t *t) { return mpldexp(t); }
nsz f9d179
int mpscalblnf(struct t *t) { return mpldexpf(t); }
nsz f9d179
int mpscalblnl(struct t *t) { return mpldexpl(t); }
nsz f9d179
nsz f9d179
int mplgamma_r(struct t *t) { return mplgamma(t); }
nsz f9d179
int mplgammaf_r(struct t *t) { return mplgammaf(t); }
nsz f9d179
int mplgammal_r(struct t *t) { return mplgammal(t); }