arb icon indicating copy to clipboard operation
arb copied to clipboard

Feature request: conversion to/from __float128 type

Open MacroUniverse opened this issue 2 years ago • 1 comments

Hi, could you add a function that initialize an arb variable from __float128 and __complex128 types that supported by GCC compiler? And also a function that converts back? I've experimented a little in c++, but not all the corner cases are considered (such as nan or inf):

typedef __float128 Qdoub;

// get a quad precision number from arf_t type
// similar to arf_get_d()
inline void arf_get_q(Qdoub &v, const arf_t x, arf_rnd_t rnd)
{
	arf_t t;
	mp_srcptr tp;
	mp_size_t tn;

	arf_init(t);
	arf_set_round(t, x, 113, rnd);
	ARF_GET_MPN_READONLY(tp, tn, t);
	if (tn == 1)
		v = (Qdoub)(tp[0]);
	else if (tn == 2)
		v = (Qdoub)(tp[1]) + (Qdoub)(tp[0]) * ldexpq(1,-FLINT_BITS);
	else if (tn == 3)
		v = (Qdoub)(tp[2]) + (Qdoub)(tp[1]) * ldexpq(1,-FLINT_BITS) + (Qdoub)(tp[0]) * ldexpq(1,-2*FLINT_BITS);
	else if (tn == 4)
		v = (Qdoub)(tp[3]) + (Qdoub)(tp[2]) * ldexpq(1,-FLINT_BITS) + (Qdoub)(tp[1]) * ldexpq(1,-2*FLINT_BITS) + (Qdoub)(tp[0]) * ldexpq(1,-3*FLINT_BITS);
	else
		cerr << "not implemented!";

	v = ldexpq(v, ARF_EXP(t) - FLINT_BITS);

	if (ARF_SGNBIT(t))
		v = -v;
	arf_clear(t);
}

// similar to arf_set_d()
inline void arf_set_q(arf_t x, const Qdoub &q0)
{
	Qdoub q = q0;
	if (sizeof(slong) != 8 || sizeof(short int) != 2)
		cerr << "something wrong!";
// delete 2 bytes sign and exponent, then split into 2 Llong types
	Uchar *p = (Uchar*)&q;
	Bool negative = bitL(p+15, 0);
	unset_bitL(p+15, 0);
    short int pw = *(short int*)(p+14) - 16383;
    p[14] = 0; p[15] = 0;
    long long *pL0 = (long long*)p;
	long long *pL1 = (long long*)(p+7);
	arf_t tmp; arf_init(tmp);
	arb_t t2; arb_init(t2);
	arf_set_si_2exp_si(x, *pL1, pw-56);
	p[7] = 0;
	arf_set_si_2exp_si(tmp, *pL0, pw-112);
	arf_add(x, x, tmp, 123, (arf_rnd_t)ARF_PREC_EXACT);
	if (pw != -16383 && pw != 16384) {
		arf_set_si_2exp_si(tmp, 1, pw);
		arf_add(x, x, tmp, 123, (arf_rnd_t)ARF_PREC_EXACT);
	}
	else
		cerr << "not implemented!";
	if (negative)
		arf_neg(x, x);
	arf_clear(tmp);
}

// similar to arb_set_d()
inline void arb_set_q(arb_t x, Qdoub_I q)
{
	arf_set_q(arb_midref(x), q);
    mag_zero(arb_radref(x));
}

MacroUniverse avatar Jun 22 '22 04:06 MacroUniverse

sounds like a job for fpwrap.c...

vale981 avatar Jun 23 '22 12:06 vale981