mirror of
https://github.com/vale981/arb
synced 2025-03-05 09:21:38 -05:00
semi-working mprb type based on mpr/mpfr + ufloat
This commit is contained in:
parent
48df1f1886
commit
9ee444f76c
33 changed files with 1513 additions and 225 deletions
|
@ -102,5 +102,5 @@ build/%.lo: %.c
|
|||
build/%.o: %.c
|
||||
$(CC) -fPIC $(CFLAGS) $(INCS) -c $< -o $@
|
||||
|
||||
BUILD_DIRS = mpr mprb
|
||||
BUILD_DIRS = ufloat mpr mprb
|
||||
|
||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -6,7 +6,7 @@
|
|||
PREFIX="/usr/local"
|
||||
MPIR_DIR="/usr/local"
|
||||
MPFR_DIR="/usr/local"
|
||||
FLINT_DIR="/home/fredrik/src/flint2/flint2"
|
||||
FLINT_DIR="/home/fredrik/src/flint2"
|
||||
SHARED=1
|
||||
STATIC=1
|
||||
|
||||
|
|
3
mpr.h
3
mpr.h
|
@ -62,7 +62,10 @@ void _mpr_printr(mp_ptr x, mp_size_t n);
|
|||
int
|
||||
_mpr_muld_n(mp_ptr z, mp_srcptr x, mp_srcptr y, mp_size_t n);
|
||||
|
||||
int _mpr_muld_using_mpfr(mp_ptr z, mp_size_t zn, mp_srcptr x, mp_size_t xn, mp_srcptr y, mp_size_t yn);
|
||||
|
||||
/* Addition ******************************************************************/
|
||||
|
||||
int _mpr_addd_n(mp_ptr z, mp_srcptr x, mp_srcptr y, mp_bitcnt_t shift, mp_size_t n);
|
||||
|
||||
int _mpr_addd_using_mpfr(mp_ptr z, mp_size_t zn, mp_srcptr x, mp_size_t xn, mp_srcptr y, mp_size_t yn, long shift);
|
||||
|
|
31
mpr/addd_using_mpfr.c
Normal file
31
mpr/addd_using_mpfr.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "mpr.h"
|
||||
|
||||
/*
|
||||
Computes z = x + y / 2^shift, rounding down (truncating) with correct rounding.
|
||||
Returns adjustment (0 or 1) to be added to the exponent.
|
||||
*/
|
||||
|
||||
int
|
||||
_mpr_addd_using_mpfr(mp_ptr z, mp_size_t zn, mp_srcptr x, mp_size_t xn, mp_srcptr y, mp_size_t yn, long shift)
|
||||
{
|
||||
__mpfr_struct zs, xs, ys;
|
||||
|
||||
xs._mpfr_d = (mp_ptr) x;
|
||||
xs._mpfr_exp = 0;
|
||||
xs._mpfr_prec = xn * FLINT_BITS;
|
||||
xs._mpfr_sign = 1;
|
||||
|
||||
ys._mpfr_d = (mp_ptr) y;
|
||||
ys._mpfr_exp = -shift;
|
||||
ys._mpfr_prec = yn * FLINT_BITS;
|
||||
ys._mpfr_sign = 1;
|
||||
|
||||
zs._mpfr_d = (mp_ptr) z;
|
||||
zs._mpfr_exp = 0;
|
||||
zs._mpfr_prec = zn * FLINT_BITS;
|
||||
zs._mpfr_sign = 1;
|
||||
|
||||
mpfr_add(&zs, &xs, &ys, MPFR_RNDD);
|
||||
|
||||
return zs._mpfr_exp != 0;
|
||||
}
|
31
mpr/muld_using_mpfr.c
Normal file
31
mpr/muld_using_mpfr.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "mpr.h"
|
||||
|
||||
/*
|
||||
Computes z = x * y, rounding down (truncating) with correct rounding.
|
||||
Returns adjustment (0 or 1) to be subtracted from the exponent.
|
||||
*/
|
||||
|
||||
int
|
||||
_mpr_muld_using_mpfr(mp_ptr z, mp_size_t zn, mp_srcptr x, mp_size_t xn, mp_srcptr y, mp_size_t yn)
|
||||
{
|
||||
__mpfr_struct zs, xs, ys;
|
||||
|
||||
xs._mpfr_d = (mp_ptr) x;
|
||||
xs._mpfr_exp = 0;
|
||||
xs._mpfr_prec = xn * FLINT_BITS;
|
||||
xs._mpfr_sign = 1;
|
||||
|
||||
ys._mpfr_d = (mp_ptr) y;
|
||||
ys._mpfr_exp = 0;
|
||||
ys._mpfr_prec = yn * FLINT_BITS;
|
||||
ys._mpfr_sign = 1;
|
||||
|
||||
zs._mpfr_d = (mp_ptr) z;
|
||||
zs._mpfr_exp = 0;
|
||||
zs._mpfr_prec = zn * FLINT_BITS;
|
||||
zs._mpfr_sign = 1;
|
||||
|
||||
mpfr_mul(&zs, &xs, &ys, MPFR_RNDD);
|
||||
|
||||
return zs._mpfr_exp != 0;
|
||||
}
|
13
mprb.h
13
mprb.h
|
@ -1,13 +1,20 @@
|
|||
#include "mpr.h"
|
||||
#include "ufloat.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mp_ptr d;
|
||||
mp_limb_t rad;
|
||||
long exp;
|
||||
long size;
|
||||
long alloc;
|
||||
long sign;
|
||||
long exp;
|
||||
int sign;
|
||||
}
|
||||
mpr_struct;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mpr_struct mid;
|
||||
ufloat_struct rad;
|
||||
}
|
||||
mprb_struct;
|
||||
|
||||
|
|
88
mprb/add.c
88
mprb/add.c
|
@ -3,83 +3,39 @@
|
|||
void
|
||||
mprb_add(mprb_t z, const mprb_t x, const mprb_t y)
|
||||
{
|
||||
mp_limb_t xrad, yrad, t, u;
|
||||
mp_srcptr xptr, yptr;
|
||||
long size, xexp, yexp, shift, carry, exp;
|
||||
mp_ptr zptr;
|
||||
long zsize, xsize, ysize, xexp, yexp, shift;
|
||||
|
||||
if (x->sign != y->sign)
|
||||
{
|
||||
printf("mprb_add: different signs not supported\n");
|
||||
if (x->mid.sign != y->mid.sign)
|
||||
abort();
|
||||
}
|
||||
|
||||
size = FLINT_MIN(x->size, y->size);
|
||||
size = FLINT_MIN(size, z->alloc);
|
||||
xrad = (size == x->size) ? x->rad : 2UL;
|
||||
yrad = (size == y->size) ? y->rad : 2UL;
|
||||
xptr = x->d + x->size - size;
|
||||
yptr = y->d + y->size - size;
|
||||
xptr = x->mid.d;
|
||||
yptr = y->mid.d;
|
||||
zptr = z->mid.d;
|
||||
|
||||
xexp = x->exp;
|
||||
yexp = y->exp;
|
||||
xsize = x->mid.size;
|
||||
ysize = y->mid.size;
|
||||
zsize = z->mid.size;
|
||||
|
||||
xexp = x->mid.exp;
|
||||
yexp = y->mid.exp;
|
||||
|
||||
ufloat_add(&z->rad, &x->rad, &y->rad);
|
||||
|
||||
z->mid.sign = x->mid.sign;
|
||||
|
||||
if (xexp >= yexp)
|
||||
{
|
||||
shift = xexp - yexp;
|
||||
carry = _mpr_addd_n(z->d, xptr, yptr, shift, size);
|
||||
exp = xexp;
|
||||
shift = _mpr_addd_using_mpfr(zptr, zsize, xptr, xsize, yptr, ysize, xexp - yexp);
|
||||
z->mid.exp = x->mid.exp + shift;
|
||||
}
|
||||
else
|
||||
{
|
||||
shift = yexp - xexp;
|
||||
carry = _mpr_addd_n(z->d, yptr, xptr, shift, size);
|
||||
t = xrad;
|
||||
xrad = yrad;
|
||||
yrad = t;
|
||||
exp = yexp;
|
||||
shift = _mpr_addd_using_mpfr(zptr, zsize, yptr, ysize, xptr, xsize, yexp - xexp);
|
||||
z->mid.exp = y->mid.exp + shift;
|
||||
}
|
||||
|
||||
xrad = (xrad >> carry) + carry;
|
||||
yrad = (yrad >> carry) + carry;
|
||||
|
||||
if (shift >= FLINT_BITS)
|
||||
{
|
||||
add_ssaaaa(u, t, 0, xrad, 0, 3);
|
||||
}
|
||||
else if (shift == 0)
|
||||
{
|
||||
add_ssaaaa(u, t, 0, xrad, 0, yrad);
|
||||
add_ssaaaa(u, t, u, t, 0, carry);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_ssaaaa(u, t, 0, xrad, 0, (yrad >> shift) + 3);
|
||||
}
|
||||
|
||||
if (u == 0)
|
||||
{
|
||||
z->rad = t;
|
||||
z->size = size;
|
||||
z->sign = x->sign;
|
||||
z->exp = exp + carry;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size == 1)
|
||||
{
|
||||
z->rad = 1UL << (FLINT_BITS - 1);
|
||||
z->d[0] = 0;
|
||||
z->size = 1;
|
||||
z->sign = x->sign;
|
||||
z->exp = exp + carry + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
z->rad = 3UL;
|
||||
mpn_copyi(z->d, z->d + 1, size - 1);
|
||||
z->size = size - 1;
|
||||
z->sign = x->sign;
|
||||
z->exp = exp + carry;
|
||||
}
|
||||
}
|
||||
/* rounding error */
|
||||
ufloat_add_2exp(&z->rad, &z->rad, z->mid.exp - z->mid.size * FLINT_BITS);
|
||||
}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
void
|
||||
mprb_clear(mprb_t x)
|
||||
{
|
||||
free(x->d);
|
||||
}
|
||||
free(x->mid.d);
|
||||
}
|
||||
|
|
|
@ -6,9 +6,10 @@ mprb_contains_mpfr(const mprb_t x, const mpfr_t f)
|
|||
mpfr_t a, b;
|
||||
int result;
|
||||
|
||||
/* 1 extra bit allows adding radius exactly */
|
||||
mpfr_init2(a, FLINT_BITS * x->size + 1);
|
||||
mpfr_init2(b, FLINT_BITS * x->size + 1);
|
||||
/* XXX: this is no longer correct if the radius is larger */
|
||||
|
||||
mpfr_init2(a, FLINT_BITS * x->mid.size + 1000);
|
||||
mpfr_init2(b, FLINT_BITS * x->mid.size + 1000);
|
||||
|
||||
mprb_get_interval_mpfr(a, b, x);
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ mprb_debug(const mprb_t x)
|
|||
mpz_init(t);
|
||||
e = mprb_get_mid_mpz_2exp(t, x);
|
||||
|
||||
printf("N: [exp=%ld] ", x->exp);
|
||||
mpn_debug(x->d, x->size);
|
||||
gmp_printf("Z: {mid=%Zx, exp=%ld, rad=%lu, size=%ld, alloc=%ld}\n",
|
||||
t, e, x->rad, (long) x->size, (long) x->alloc);
|
||||
printf("N: [exp=%ld] ", x->mid.exp);
|
||||
mpn_debug(x->mid.d, x->mid.size);
|
||||
gmp_printf("Z: {%Zd * 2^%ld +- %lu * 2^%ld, size=%ld, alloc=%ld}\n",
|
||||
t, e, x->rad.man, x->rad.exp - UFLOAT_PREC, (long) x->mid.size, (long) x->mid.alloc);
|
||||
|
||||
mpz_clear(t);
|
||||
}
|
||||
|
|
|
@ -11,20 +11,8 @@ mprb_get_interval_mpfr(mpfr_t a, mpfr_t b, const mprb_t x)
|
|||
|
||||
mprb_get_rad_mpfr(r, x);
|
||||
|
||||
#if 0
|
||||
printf("GETTING INTRVLA\n");
|
||||
mpfr_printf("a = %Rg [xsign = %ld]\n", a, x->sign);
|
||||
mpfr_printf("b = %Rg\n", b);
|
||||
mpfr_printf("r = %Rg\n", r);
|
||||
#endif
|
||||
|
||||
mpfr_sub(a, a, r, MPFR_RNDD);
|
||||
mpfr_add(b, b, r, MPFR_RNDU);
|
||||
|
||||
#if 0
|
||||
mpfr_printf("a2 = %Rg\n", a);
|
||||
mpfr_printf("b2 = %Rg\n", b);
|
||||
#endif
|
||||
|
||||
mpfr_clear(r);
|
||||
}
|
||||
|
|
|
@ -4,9 +4,8 @@
|
|||
void
|
||||
mprb_get_mid_mpfr(mpfr_t x, const mprb_t v, mpfr_rnd_t rnd)
|
||||
{
|
||||
if ((v->size == 1) && (v->d[0] == 0))
|
||||
if ((v->mid.size == 1) && (v->mid.d[0] == 0))
|
||||
mpfr_set_ui(x, 0, MPFR_RNDD);
|
||||
else
|
||||
_mpr_get_mpfr_signed(x, v->d, v->exp, v->size,
|
||||
(v->sign == MPRB_SIGN_PLUS) ? 1 : -1, rnd);
|
||||
_mpr_get_mpfr_signed(x, v->mid.d, v->mid.exp, v->mid.size, (v->mid.sign == MPRB_SIGN_PLUS) ? 1 : -1, rnd);
|
||||
}
|
||||
|
|
|
@ -4,16 +4,16 @@
|
|||
long
|
||||
mprb_get_mid_mpz_2exp(mpz_t a, const mprb_t x)
|
||||
{
|
||||
if ((x->size == 1) && (x->d[0] == 0))
|
||||
if ((x->mid.size == 1) && (x->mid.d[0] == 0))
|
||||
{
|
||||
mpz_set_ui(a, 0);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mpz_realloc2(a, x->size * FLINT_BITS);
|
||||
mpn_copyi(a->_mp_d, x->d, x->size);
|
||||
a->_mp_size = (x->sign == MPRB_SIGN_PLUS) ? x->size : -(x->size);
|
||||
return x->exp - x->size * FLINT_BITS;
|
||||
mpz_realloc2(a, x->mid.size * FLINT_BITS);
|
||||
mpn_copyi(a->_mp_d, x->mid.d, x->mid.size);
|
||||
a->_mp_size = (x->mid.sign == MPRB_SIGN_PLUS) ? x->mid.size : -(x->mid.size);
|
||||
return x->mid.exp - x->mid.size * FLINT_BITS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
void
|
||||
mprb_get_rad_mpfr(mpfr_t r, const mprb_t x)
|
||||
{
|
||||
mpfr_set_ui_2exp(r, x->rad, x->exp - FLINT_BITS * x->size, MPFR_RNDU);
|
||||
ufloat_get_mpfr(r, &x->rad);
|
||||
}
|
||||
|
|
15
mprb/init.c
15
mprb/init.c
|
@ -5,10 +5,13 @@ mprb_init(mprb_t x, long bits)
|
|||
{
|
||||
long limbs = _MPR_BITS_TO_LIMBS(bits);
|
||||
|
||||
x->d = calloc(limbs, sizeof(mp_limb_t));
|
||||
x->exp = 0;
|
||||
x->sign = MPRB_SIGN_PLUS;
|
||||
x->alloc = limbs;
|
||||
x->size = limbs;
|
||||
x->rad = 0UL;
|
||||
x->mid.d = calloc(limbs, sizeof(mp_limb_t));
|
||||
x->mid.exp = 0;
|
||||
x->mid.sign = MPRB_SIGN_PLUS;
|
||||
x->mid.alloc = limbs;
|
||||
x->mid.size = limbs;
|
||||
|
||||
/* XXX: ufloat_zero */
|
||||
x->rad.man = 0UL;
|
||||
x->rad.exp = 0L;
|
||||
}
|
||||
|
|
137
mprb/mul.c
137
mprb/mul.c
|
@ -1,114 +1,55 @@
|
|||
#include "mprb.h"
|
||||
|
||||
/* throw away to avoid overflow */
|
||||
#define RAD_MUL_SHIFT 8
|
||||
|
||||
/* XXX: assumes nonzero! */
|
||||
static __inline__ void
|
||||
_mpr_get_ufloat(ufloat_t u, mp_srcptr d, long size, long exp)
|
||||
{
|
||||
/* since we truncate, we need to round up */
|
||||
u->man = (d[size - 1] >> (FLINT_BITS - UFLOAT_PREC)) + 1UL;
|
||||
u->exp = exp;
|
||||
|
||||
/* adjust for carry (very unlikely!) */
|
||||
if (u->man >= (1UL << UFLOAT_PREC))
|
||||
{
|
||||
u->man = (u->man >> 1) + 1UL;
|
||||
u->exp++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mprb_mul(mprb_t z, const mprb_t x, const mprb_t y)
|
||||
{
|
||||
mp_limb_t xrad, yrad;
|
||||
ufloat_t a, b;
|
||||
mp_srcptr xptr, yptr;
|
||||
long size;
|
||||
mp_ptr zptr;
|
||||
long zsize, xsize, ysize, exp, shift;
|
||||
|
||||
size = FLINT_MIN(x->size, y->size);
|
||||
size = FLINT_MIN(size, z->alloc);
|
||||
xrad = (size == x->size) ? x->rad : 2UL;
|
||||
yrad = (size == y->size) ? y->rad : 2UL;
|
||||
xptr = x->d + x->size - size;
|
||||
yptr = y->d + y->size - size;
|
||||
xptr = x->mid.d;
|
||||
yptr = y->mid.d;
|
||||
zptr = z->mid.d;
|
||||
|
||||
if (size == 1)
|
||||
{
|
||||
mp_limb_t u1, u0, a2, a1, a0, b1, b0;
|
||||
xsize = x->mid.size;
|
||||
ysize = y->mid.size;
|
||||
zsize = z->mid.size;
|
||||
|
||||
umul_ppmm(a1, a0, xptr[0], yrad);
|
||||
umul_ppmm(b1, b0, yptr[0], xrad);
|
||||
add_sssaaaaaa(a2, a1, a0, 0, a1, a0, 0, b1, b0);
|
||||
umul_ppmm(b1, b0, xrad, yrad);
|
||||
add_sssaaaaaa(a2, a1, a0, a2, a1, a0, 0, b1, b0);
|
||||
_mpr_get_ufloat(a, xptr, xsize, x->mid.exp);
|
||||
_mpr_get_ufloat(b, yptr, ysize, y->mid.exp);
|
||||
|
||||
umul_ppmm(u1, u0, xptr[0], yptr[0]);
|
||||
/* error propagation: x*rad(y) + y*rad(x) + rad(x)*rad(y) */
|
||||
ufloat_mul(a, a, &y->rad);
|
||||
ufloat_addmul(a, b, &x->rad);
|
||||
ufloat_add_2exp(a, a, x->rad.exp + y->rad.exp);
|
||||
|
||||
if ((u1 >> (FLINT_BITS - 1)) == 0)
|
||||
{
|
||||
u1 = (u1 << 1) | (u0 >> (FLINT_BITS - 1));
|
||||
u0 = (u0 << 1);
|
||||
a2 = (a2 << 1) | (a1 >> (FLINT_BITS - 1));
|
||||
a1 = (a1 << 1) | (a0 >> (FLINT_BITS - 1));
|
||||
a0 = (a0 << 1);
|
||||
z->exp = x->exp + y->exp - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
z->exp = x->exp + y->exp;
|
||||
}
|
||||
shift = _mpr_muld_using_mpfr(zptr, zsize, xptr, xsize, yptr, ysize);
|
||||
|
||||
/* round up */
|
||||
add_ssaaaa(a2, a1, a2, a1, 0, (u0 != 0) + (a0 != 0));
|
||||
/* add exponents */
|
||||
exp = x->mid.exp + y->mid.exp - shift;
|
||||
|
||||
if (a2 == 0)
|
||||
{
|
||||
z->rad = a1;
|
||||
z->d[0] = u1;
|
||||
}
|
||||
else
|
||||
{
|
||||
z->rad = -1UL;
|
||||
z->d[0] = (1UL << (FLINT_BITS - 1));
|
||||
z->exp += 2;
|
||||
}
|
||||
/* rounding error */
|
||||
ufloat_add_2exp(a, a, exp - z->mid.size * FLINT_BITS);
|
||||
|
||||
z->size = 1;
|
||||
z->sign = x->sign ^ y->sign;
|
||||
}
|
||||
else
|
||||
{
|
||||
mp_limb_t t0, t1, u0, u1, rad;
|
||||
mp_limb_t xtop, ytop;
|
||||
int shift, need_limb_shift;
|
||||
|
||||
/* upper bound for x*yrad + y*xrad */
|
||||
xtop = (xptr[size-1] >> RAD_MUL_SHIFT) + 1UL;
|
||||
ytop = (yptr[size-1] >> RAD_MUL_SHIFT) + 1UL;
|
||||
umul_ppmm(t1, t0, xtop, y->rad);
|
||||
umul_ppmm(u1, u0, ytop, x->rad);
|
||||
add_ssaaaa(t1, t0, t1, t0, u1, u0);
|
||||
|
||||
/* scale back radius to the true magnitude */
|
||||
t0 = (t0 >> (FLINT_BITS - RAD_MUL_SHIFT)) | (t1 << RAD_MUL_SHIFT);
|
||||
t1 = (t1 >> (FLINT_BITS - RAD_MUL_SHIFT));
|
||||
|
||||
/* xrad * yrad < 1 ulp
|
||||
+ 1 ulp error in the main multiplication
|
||||
+ 1 ulp error from the shift above */
|
||||
add_ssaaaa(t1, t0, t1, t0, 0, 3UL);
|
||||
|
||||
shift = _mpr_muld_n(z->d, xptr, yptr, size);
|
||||
|
||||
/* adjust radius */
|
||||
t1 = (t1 << shift) | ((t0 >> (FLINT_BITS - 1)) & shift);
|
||||
t0 = t0 << shift;
|
||||
|
||||
/* remove one limb */
|
||||
if (t1 != 0)
|
||||
{
|
||||
need_limb_shift = 1;
|
||||
|
||||
/* +1 ulp error for the rounding of t1 */
|
||||
/* +1 ulp error in the main product, which doubles
|
||||
if we perform a shift */
|
||||
rad = t1 + 2 + shift;
|
||||
mpn_copyi(z->d, z->d + 1, size - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
need_limb_shift = 0;
|
||||
rad = t0;
|
||||
}
|
||||
|
||||
z->rad = rad;
|
||||
z->exp = x->exp + y->exp - shift;
|
||||
z->size = size - need_limb_shift;
|
||||
z->sign = x->sign ^ y->sign;
|
||||
}
|
||||
z->rad = *a;
|
||||
z->mid.exp = exp;
|
||||
z->mid.sign = x->mid.sign ^ y->mid.sign;
|
||||
}
|
||||
|
|
|
@ -5,12 +5,14 @@ mprb_randtest(mprb_t x, flint_rand_t state, long emin, long emax)
|
|||
{
|
||||
long n;
|
||||
|
||||
n = n_randint(state, x->alloc) + 1;
|
||||
n = n_randint(state, x->mid.alloc) + 1;
|
||||
|
||||
_mpr_randtest(x->d, state, n);
|
||||
_mpr_randtest(x->mid.d, state, n);
|
||||
|
||||
x->rad = n_randtest(state);
|
||||
x->size = n;
|
||||
x->sign = n_randint(state, 2) ? MPRB_SIGN_PLUS : MPRB_SIGN_MINUS;
|
||||
x->exp = emin + n_randint(state, emax - emin + 1);
|
||||
x->mid.size = n;
|
||||
x->mid.sign = n_randint(state, 2) ? MPRB_SIGN_PLUS : MPRB_SIGN_MINUS;
|
||||
x->mid.exp = emin + n_randint(state, emax - emin + 1);
|
||||
|
||||
/* XXX: change ufloat_randtest to use emin / emax */
|
||||
ufloat_randtest(&x->rad, state, emax);
|
||||
}
|
||||
|
|
|
@ -6,11 +6,21 @@ mprb_set_mpfr(mprb_t x, const mpfr_t v)
|
|||
{
|
||||
long xprec, vprec, prec;
|
||||
|
||||
xprec = x->alloc;
|
||||
xprec = x->mid.alloc;
|
||||
vprec = _MPR_BITS_TO_LIMBS(v->_mpfr_prec);
|
||||
|
||||
x->exp = _mpr_set_mpfr(x->d, v, xprec);
|
||||
x->rad = (xprec >= vprec) ? 0UL : 1UL;
|
||||
x->sign = (v->_mpfr_sign == 1) ? MPRB_SIGN_PLUS : MPRB_SIGN_MINUS;
|
||||
x->size = x->alloc;
|
||||
x->mid.exp = _mpr_set_mpfr(x->mid.d, v, xprec);
|
||||
x->mid.sign = (v->_mpfr_sign == 1) ? MPRB_SIGN_PLUS : MPRB_SIGN_MINUS;
|
||||
x->mid.size = x->mid.alloc;
|
||||
|
||||
if (xprec >= vprec)
|
||||
{
|
||||
ufloat_zero(&x->rad);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* max 1 ulp error */
|
||||
/* XXX: ufloat_set_2exp */
|
||||
ufloat_set_ui_2exp(&x->rad, 1UL, x->mid.exp - x->mid.size * FLINT_BITS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ int main()
|
|||
mprb_init(y, 1 + n_randint(state, 300));
|
||||
mprb_init(z, 1 + n_randint(state, 300));
|
||||
|
||||
do { mprb_randtest(x, state, -10, 10); } while (x->size == 0);
|
||||
do { mprb_randtest(y, state, -10, 10); } while (y->size == 0);
|
||||
do { mprb_randtest(z, state, -10, 10); } while (z->size == 0);
|
||||
do { mprb_randtest(x, state, -10, 10); } while (x->mid.size == 0);
|
||||
do { mprb_randtest(y, state, -10, 10); } while (y->mid.size == 0);
|
||||
do { mprb_randtest(z, state, -10, 10); } while (z->mid.size == 0);
|
||||
|
||||
y->sign = x->sign;
|
||||
y->mid.sign = x->mid.sign;
|
||||
|
||||
mpfr_init2(t, 1000);
|
||||
mpfr_init2(u, 1000);
|
||||
|
@ -76,4 +76,4 @@ int main()
|
|||
flint_randclear(state);
|
||||
_fmpz_cleanup();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,9 +26,9 @@ int main()
|
|||
mprb_init(y, 1 + n_randint(state, 300));
|
||||
mprb_init(z, 1 + n_randint(state, 300));
|
||||
|
||||
do { mprb_randtest(x, state, -10, 10); } while (x->size == 0);
|
||||
do { mprb_randtest(y, state, -10, 10); } while (y->size == 0);
|
||||
do { mprb_randtest(z, state, -10, 10); } while (z->size == 0);
|
||||
do { mprb_randtest(x, state, -10, 10); } while (x->mid.size == 0);
|
||||
do { mprb_randtest(y, state, -10, 10); } while (y->mid.size == 0);
|
||||
do { mprb_randtest(z, state, -10, 10); } while (z->mid.size == 0);
|
||||
|
||||
mpfr_init2(t, 1000);
|
||||
mpfr_init2(u, 1000);
|
||||
|
@ -74,4 +74,4 @@ int main()
|
|||
flint_randclear(state);
|
||||
_fmpz_cleanup();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
418
ufloat.h
Normal file
418
ufloat.h
Normal file
|
@ -0,0 +1,418 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of ARB.
|
||||
|
||||
ARB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ARB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ARB; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef UFLOAT_H
|
||||
#define UFLOAT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <mpir.h>
|
||||
#include "flint.h"
|
||||
#include "fmpz.h"
|
||||
#include "ulong_extras.h"
|
||||
#include "math.h"
|
||||
|
||||
static __inline__ mp_limb_t
|
||||
n_rshift_ceil(mp_limb_t a, int k)
|
||||
{
|
||||
return (a >> k) + (((a >> k) << k) != a);
|
||||
}
|
||||
|
||||
/*
|
||||
A ufloat holds a nonzero bound for the magnitude of a number.
|
||||
The mantissa has exactly UFLOAT_PREC bits, which must be at most
|
||||
FLINT_BITS / 2.
|
||||
*/
|
||||
|
||||
#define UFLOAT_PREC 15
|
||||
#define UFLOAT_MAN_MIN (1UL << (UFLOAT_PREC - 1))
|
||||
#define UFLOAT_MAN_MAX ((1UL << UFLOAT_PREC) - 1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mp_limb_t man;
|
||||
long exp;
|
||||
}
|
||||
ufloat_struct;
|
||||
|
||||
typedef ufloat_struct ufloat_t[1];
|
||||
|
||||
static __inline__ void
|
||||
ufloat_print(const ufloat_t x)
|
||||
{
|
||||
double t = ldexp(x->man, x->exp - UFLOAT_PREC);
|
||||
|
||||
printf("ufloat{man=%lu, exp=%ld, %.20g}\n", x->man, x->exp, t);
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_normalise(ufloat_t z)
|
||||
{
|
||||
int b = FLINT_BIT_COUNT(z->man);
|
||||
|
||||
if (b < UFLOAT_PREC)
|
||||
{
|
||||
z->man <<= (UFLOAT_PREC - b);
|
||||
z->exp -= (UFLOAT_PREC - b);
|
||||
}
|
||||
else
|
||||
{
|
||||
int adjust;
|
||||
|
||||
z->man = n_rshift_ceil(z->man, (b - UFLOAT_PREC));
|
||||
z->exp += (b - UFLOAT_PREC);
|
||||
|
||||
/* possible overflow to power of two */
|
||||
adjust = z->man >> UFLOAT_PREC;
|
||||
z->man = n_rshift_ceil(z->man, adjust);
|
||||
z->exp += adjust;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static __inline__ int
|
||||
ufloat_cmp_one(const ufloat_t u)
|
||||
{
|
||||
if (u->exp == 1L)
|
||||
return u->man == (1UL << (UFLOAT_PREC - 1)) ? 0 : 1;
|
||||
else
|
||||
return u->exp < 1L ? -1 : 1;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_set(ufloat_t u, const ufloat_t v)
|
||||
{
|
||||
u->man = v->man;
|
||||
u->exp = v->exp;
|
||||
}
|
||||
|
||||
|
||||
static __inline__ void
|
||||
ufloat_zero(ufloat_t u)
|
||||
{
|
||||
u->man = 0UL;
|
||||
u->exp = 0L;
|
||||
}
|
||||
|
||||
/* TODO: add constant_p handling; overflow */
|
||||
static __inline__ void
|
||||
ufloat_set_ui_2exp(ufloat_t u, mp_limb_t a, long exp)
|
||||
{
|
||||
u->man = a;
|
||||
u->exp = exp + UFLOAT_PREC;
|
||||
ufloat_normalise(u);
|
||||
}
|
||||
|
||||
/* TODO: overflow */
|
||||
static __inline__ void
|
||||
ufloat_set_ll_2exp(ufloat_t u, mp_limb_t hi, mp_limb_t lo, long exp)
|
||||
{
|
||||
if (hi == 0UL)
|
||||
{
|
||||
ufloat_set_ui_2exp(u, lo, exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int c;
|
||||
count_leading_zeros(c, hi);
|
||||
|
||||
if (c != 0)
|
||||
hi = (hi << c) | (lo >> (FLINT_BITS - c));
|
||||
|
||||
if (hi + 1UL != 0UL)
|
||||
ufloat_set_ui_2exp(u, hi + 1UL, exp + FLINT_BITS - c);
|
||||
else
|
||||
ufloat_set_ui_2exp(u, 1UL, exp + 2 * FLINT_BITS - c);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_one(ufloat_t u)
|
||||
{
|
||||
u->man = (1UL << (UFLOAT_PREC - 1));
|
||||
u->exp = 1L;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_add(ufloat_t z, const ufloat_t x, const ufloat_t y)
|
||||
{
|
||||
long shift;
|
||||
int adjust;
|
||||
|
||||
shift = x->exp - y->exp;
|
||||
|
||||
if (shift >= 0)
|
||||
{
|
||||
z->exp = x->exp;
|
||||
if (shift >= UFLOAT_PREC)
|
||||
z->man = x->man + 1;
|
||||
else
|
||||
z->man = x->man + n_rshift_ceil(y->man, shift);
|
||||
}
|
||||
else
|
||||
{
|
||||
shift = -shift;
|
||||
z->exp = y->exp;
|
||||
if (shift >= UFLOAT_PREC)
|
||||
z->man = y->man + 1;
|
||||
else
|
||||
z->man = y->man + n_rshift_ceil(x->man, shift);
|
||||
}
|
||||
|
||||
/* adjust for carry */
|
||||
adjust = z->man >> UFLOAT_PREC;
|
||||
z->man = n_rshift_ceil(z->man, adjust);
|
||||
z->exp += adjust;
|
||||
}
|
||||
|
||||
/* bound |x-y| */
|
||||
static __inline__ void
|
||||
ufloat_sub(ufloat_t z, const ufloat_t x, const ufloat_t y)
|
||||
{
|
||||
long shift;
|
||||
|
||||
mp_limb_t a, b;
|
||||
|
||||
shift = x->exp - y->exp;
|
||||
|
||||
if (shift == 0)
|
||||
{
|
||||
if (x->man >= y->man)
|
||||
z->man = x->man - y->man;
|
||||
else
|
||||
z->man = y->man - x->man;
|
||||
z->exp = x->exp;
|
||||
ufloat_normalise(z);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shift > 0)
|
||||
{
|
||||
z->exp = x->exp;
|
||||
a = x->man;
|
||||
b = y->man;
|
||||
}
|
||||
else
|
||||
{
|
||||
shift = -shift;
|
||||
z->exp = y->exp;
|
||||
a = y->man;
|
||||
b = x->man;
|
||||
}
|
||||
|
||||
if (shift >= UFLOAT_PREC)
|
||||
{
|
||||
z->man = a;
|
||||
}
|
||||
else
|
||||
{
|
||||
z->man = (a << shift) - b;
|
||||
z->exp -= shift;
|
||||
}
|
||||
|
||||
ufloat_normalise(z);
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_set_2exp(ufloat_t y, const ufloat_t x, long exp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_add_2exp(ufloat_t y, const ufloat_t x, long exp)
|
||||
{
|
||||
long s, shift = x->exp - exp;
|
||||
|
||||
/* x is larger than 2^exp */
|
||||
if (shift > 0)
|
||||
{
|
||||
s = FLINT_MAX(0L, UFLOAT_PREC - shift);
|
||||
y->man = x->man + (1UL << s);
|
||||
y->exp = x->exp;
|
||||
}
|
||||
/* 2^exp is larger than x */
|
||||
else
|
||||
{
|
||||
s = FLINT_MIN(UFLOAT_PREC - 1L, 1L - shift);
|
||||
y->man = (1UL << (UFLOAT_PREC - 1)) + (x->man >> s) + 1UL;
|
||||
y->exp = exp + 1L;
|
||||
}
|
||||
|
||||
/* unlikely */
|
||||
if (y->man > UFLOAT_MAN_MAX)
|
||||
{
|
||||
y->man = n_rshift_ceil(y->man, 1);
|
||||
y->exp++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static __inline__ void
|
||||
ufloat_mul(ufloat_t z, const ufloat_t x, const ufloat_t y)
|
||||
{
|
||||
mp_limb_t m;
|
||||
int adjust, shift;
|
||||
|
||||
z->exp = x->exp + y->exp;
|
||||
m = x->man * y->man;
|
||||
|
||||
/* product has one bit too little */
|
||||
adjust = m >> (2 * UFLOAT_PREC - 1);
|
||||
shift = UFLOAT_PREC - 1 + adjust;
|
||||
z->exp += shift;
|
||||
|
||||
m = n_rshift_ceil(m, shift);
|
||||
|
||||
/* power of two */
|
||||
adjust = m >> UFLOAT_PREC;
|
||||
m >>= adjust;
|
||||
z->exp += adjust;
|
||||
|
||||
z->man = m;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_addmul(ufloat_t z, const ufloat_t x, const ufloat_t y)
|
||||
{
|
||||
ufloat_t t;
|
||||
ufloat_mul(t, x, y);
|
||||
ufloat_add(z, z, t);
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_div(ufloat_t z, const ufloat_t x, const ufloat_t y)
|
||||
{
|
||||
int adjust;
|
||||
|
||||
z->man = (x->man << UFLOAT_PREC) / y->man + 1;
|
||||
z->exp = x->exp - y->exp;
|
||||
|
||||
/* quotient can be one bit too large */
|
||||
adjust = z->man >> UFLOAT_PREC;
|
||||
z->man = n_rshift_ceil(z->man, adjust);
|
||||
z->exp += adjust;
|
||||
|
||||
/* power of two */
|
||||
adjust = z->man >> UFLOAT_PREC;
|
||||
z->man >>= adjust;
|
||||
z->exp += adjust;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_randtest(ufloat_t u, flint_rand_t state, long erange)
|
||||
{
|
||||
u->man = n_randbits(state, UFLOAT_PREC);
|
||||
u->man |= (1UL << (UFLOAT_PREC - 1));
|
||||
u->exp = n_randint(state, erange) - (erange / 2) + 1;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_set_fmpz(ufloat_t u, const fmpz_t z)
|
||||
{
|
||||
u->man = fmpz_abs_ubound_ui_2exp(&u->exp, z, UFLOAT_PREC);
|
||||
u->exp += UFLOAT_PREC;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_set_fmpz_lower(ufloat_t u, const fmpz_t z)
|
||||
{
|
||||
u->man = fmpz_abs_lbound_ui_2exp(&u->exp, z, UFLOAT_PREC);
|
||||
u->exp += UFLOAT_PREC;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_get_fmpz(fmpz_t z, const ufloat_t u)
|
||||
{
|
||||
long exp = u->exp - UFLOAT_PREC;
|
||||
|
||||
_fmpz_demote(z);
|
||||
*z = u->man;
|
||||
|
||||
if (exp >= 0)
|
||||
{
|
||||
if (exp < FLINT_BITS - UFLOAT_PREC - 2)
|
||||
*z = (u->man << exp);
|
||||
else
|
||||
fmpz_mul_2exp(z, z, exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (exp > -FLINT_BITS)
|
||||
*z = n_rshift_ceil(u->man, -exp);
|
||||
else
|
||||
*z = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ int
|
||||
ufloat_equal(const ufloat_t u, const ufloat_t v)
|
||||
{
|
||||
return u->man == v->man && u->exp == v->exp;
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_get_mpfr(mpfr_t x, const ufloat_t u)
|
||||
{
|
||||
mpfr_set_ui_2exp(x, u->man, u->exp - UFLOAT_PREC, MPFR_RNDU);
|
||||
}
|
||||
|
||||
static __inline__ void
|
||||
ufloat_set_mpfr(ufloat_t u, const mpfr_t x)
|
||||
{
|
||||
if (mpfr_zero_p(x))
|
||||
{
|
||||
u->man = 0;
|
||||
u->exp = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mpz_t t;
|
||||
long exp, bits;
|
||||
|
||||
mpz_init(t);
|
||||
exp = mpfr_get_z_2exp(t, x);
|
||||
mpz_abs(t, t);
|
||||
|
||||
bits = mpz_sizeinbase(t, 2);
|
||||
|
||||
if (bits > UFLOAT_PREC)
|
||||
{
|
||||
mpz_cdiv_q_2exp(t, t, bits - UFLOAT_PREC);
|
||||
exp += bits - UFLOAT_PREC;
|
||||
}
|
||||
|
||||
u->exp = exp + UFLOAT_PREC;
|
||||
u->man = mpz_get_ui(t);
|
||||
ufloat_normalise(u);
|
||||
|
||||
mpz_clear(t);
|
||||
}
|
||||
}
|
||||
|
||||
void ufloat_log(ufloat_t z, const ufloat_t x);
|
||||
|
||||
void ufloat_log1p(ufloat_t z, const ufloat_t x);
|
||||
|
||||
#endif
|
42
ufloat/Makefile
Normal file
42
ufloat/Makefile
Normal file
|
@ -0,0 +1,42 @@
|
|||
SOURCES = $(wildcard *.c)
|
||||
|
||||
OBJS = $(patsubst %.c, $(BUILD_DIR)/%.o, $(SOURCES))
|
||||
|
||||
LIB_OBJS = $(patsubst %.c, $(BUILD_DIR)/%.lo, $(SOURCES))
|
||||
|
||||
TEST_SOURCES = $(wildcard test/*.c)
|
||||
|
||||
PROF_SOURCES = $(wildcard profile/*.c)
|
||||
|
||||
TUNE_SOURCES = $(wildcard tune/*.c)
|
||||
|
||||
TESTS = $(patsubst %.c, %, $(TEST_SOURCES))
|
||||
|
||||
PROFS = $(patsubst %.c, %, $(PROF_SOURCES))
|
||||
|
||||
TUNE = $(patsubst %.c, %, $(TUNE_SOURCES))
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
library: $(LIB_OBJS)
|
||||
|
||||
profile:
|
||||
$(foreach prog, $(PROFS), $(CC) -O2 -std=c99 $(INCS) $(prog).c ../profiler.o -o $(BUILD_DIR)/$(prog) $(LIBS) -lflint;)
|
||||
|
||||
tune: $(TUNE_SOURCES)
|
||||
$(foreach prog, $(TUNE), $(CC) -O2 -std=c99 $(INCS) $(prog).c -o $(BUILD_DIR)/$(prog) $(LIBS) -lflint;)
|
||||
|
||||
$(BUILD_DIR)/%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $(INCS) $< -o $@
|
||||
|
||||
$(BUILD_DIR)/%.lo: %.c
|
||||
$(CC) -fPIC $(CFLAGS) $(INCS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
|
||||
check: library
|
||||
$(foreach prog, $(TESTS), $(CC) $(CFLAGS) $(INCS) $(prog).c -o $(BUILD_DIR)/$(prog) $(LIBS) -lflint;)
|
||||
$(foreach prog, $(TESTS), $(BUILD_DIR)/$(prog);)
|
||||
|
||||
.PHONY: profile clean check all
|
44
ufloat/log.c
Normal file
44
ufloat/log.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of FLINT.
|
||||
|
||||
FLINT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FLINT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FLINT; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "ufloat.h"
|
||||
|
||||
/* upper bound for log(2) */
|
||||
#define LOG2 2977044472UL
|
||||
#define LOG2_PREC 32
|
||||
|
||||
void
|
||||
ufloat_log(ufloat_t z, const ufloat_t x)
|
||||
{
|
||||
if (ufloat_cmp_one(x) <= 0)
|
||||
ufloat_zero(z);
|
||||
else
|
||||
{
|
||||
mp_limb_t hi, lo;
|
||||
|
||||
umul_ppmm(hi, lo, x->exp, LOG2);
|
||||
ufloat_set_ll_2exp(z, hi, lo, -LOG2_PREC);
|
||||
}
|
||||
}
|
44
ufloat/log1p.c
Normal file
44
ufloat/log1p.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of FLINT.
|
||||
|
||||
FLINT is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FLINT is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with FLINT; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "ufloat.h"
|
||||
|
||||
void
|
||||
ufloat_log1p(ufloat_t z, const ufloat_t x)
|
||||
{
|
||||
ufloat_t t;
|
||||
|
||||
if (x->exp >= -1L)
|
||||
{
|
||||
ufloat_one(t);
|
||||
ufloat_add(t, t, x);
|
||||
ufloat_log(z, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* log(1+x) <= x, todo: improve accuracy */
|
||||
ufloat_set(z, x);
|
||||
}
|
||||
}
|
87
ufloat/test/t-add.c
Normal file
87
ufloat/test/t-add.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of ARB.
|
||||
|
||||
ARB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ARB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ARB; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "ufloat.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
long iter;
|
||||
flint_rand_t state;
|
||||
|
||||
printf("add....");
|
||||
fflush(stdout);
|
||||
|
||||
flint_randinit(state);
|
||||
|
||||
for (iter = 0; iter < 1000000; iter++)
|
||||
{
|
||||
fmpz_t x, y, xy, z;
|
||||
ufloat_t u, v, w;
|
||||
|
||||
fmpz_init(x);
|
||||
fmpz_init(y);
|
||||
fmpz_init(xy);
|
||||
fmpz_init(z);
|
||||
|
||||
fmpz_randtest_not_zero(x, state, 1 + n_randint(state, 500));
|
||||
fmpz_randtest_not_zero(y, state, 1 + n_randint(state, 500));
|
||||
|
||||
ufloat_set_fmpz(u, x);
|
||||
ufloat_set_fmpz(v, y);
|
||||
|
||||
ufloat_add(w, u, v);
|
||||
|
||||
fmpz_add(xy, x, y);
|
||||
|
||||
ufloat_get_fmpz(z, w);
|
||||
|
||||
if (fmpz_cmpabs(z, xy) < 0)
|
||||
{
|
||||
printf("fail!\n");
|
||||
printf("x = "); fmpz_print(x); printf("\n\n");
|
||||
printf("y = "); fmpz_print(y); printf("\n\n");
|
||||
printf("xy = "); fmpz_print(xy); printf("\n\n");
|
||||
printf("z = "); fmpz_print(z); printf("\n\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (FLINT_BIT_COUNT(w->man) != UFLOAT_PREC)
|
||||
{
|
||||
printf("wrong number of bits!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
fmpz_clear(x);
|
||||
fmpz_clear(y);
|
||||
fmpz_clear(xy);
|
||||
fmpz_clear(z);
|
||||
}
|
||||
|
||||
flint_randclear(state);
|
||||
_fmpz_cleanup();
|
||||
printf("PASS\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
88
ufloat/test/t-add_2exp.c
Normal file
88
ufloat/test/t-add_2exp.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of ARB.
|
||||
|
||||
ARB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ARB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ARB; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "ufloat.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
long iter;
|
||||
flint_rand_t state;
|
||||
|
||||
printf("add_2exp....");
|
||||
fflush(stdout);
|
||||
|
||||
flint_randinit(state);
|
||||
|
||||
for (iter = 0; iter < 1000000; iter++)
|
||||
{
|
||||
fmpz_t x, y, xy, z;
|
||||
ufloat_t u, w;
|
||||
long exp;
|
||||
|
||||
fmpz_init(x);
|
||||
fmpz_init(y);
|
||||
fmpz_init(xy);
|
||||
fmpz_init(z);
|
||||
|
||||
fmpz_randtest_not_zero(x, state, 1 + n_randint(state, 500));
|
||||
exp = n_randint(state, 500);
|
||||
fmpz_set_ui(y, 1UL);
|
||||
fmpz_mul_2exp(y, y, exp);
|
||||
|
||||
ufloat_set_fmpz(u, x);
|
||||
ufloat_add_2exp(w, u, exp);
|
||||
|
||||
fmpz_add(xy, x, y);
|
||||
|
||||
ufloat_get_fmpz(z, w);
|
||||
|
||||
if (fmpz_cmpabs(z, xy) < 0)
|
||||
{
|
||||
printf("fail!\n");
|
||||
printf("x = "); fmpz_print(x); printf("\n\n");
|
||||
printf("y = "); fmpz_print(y); printf("\n\n");
|
||||
printf("xy = "); fmpz_print(xy); printf("\n\n");
|
||||
printf("z = "); fmpz_print(z); printf("\n\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (FLINT_BIT_COUNT(w->man) != UFLOAT_PREC)
|
||||
{
|
||||
printf("wrong number of bits!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
fmpz_clear(x);
|
||||
fmpz_clear(y);
|
||||
fmpz_clear(xy);
|
||||
fmpz_clear(z);
|
||||
}
|
||||
|
||||
flint_randclear(state);
|
||||
_fmpz_cleanup();
|
||||
printf("PASS\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
89
ufloat/test/t-addmul.c
Normal file
89
ufloat/test/t-addmul.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of ARB.
|
||||
|
||||
ARB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ARB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ARB; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "ufloat.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
long iter;
|
||||
flint_rand_t state;
|
||||
|
||||
printf("addmul....");
|
||||
fflush(stdout);
|
||||
|
||||
flint_randinit(state);
|
||||
|
||||
for (iter = 0; iter < 1000000; iter++)
|
||||
{
|
||||
fmpz_t x, y, s, z;
|
||||
ufloat_t u, v, w;
|
||||
|
||||
fmpz_init(x);
|
||||
fmpz_init(y);
|
||||
fmpz_init(s);
|
||||
fmpz_init(z);
|
||||
|
||||
fmpz_randtest_not_zero(x, state, 1 + n_randint(state, 500));
|
||||
fmpz_randtest_not_zero(y, state, 1 + n_randint(state, 500));
|
||||
fmpz_randtest_not_zero(s, state, 1 + n_randint(state, 500));
|
||||
|
||||
ufloat_set_fmpz(u, x);
|
||||
ufloat_set_fmpz(v, y);
|
||||
ufloat_set_fmpz(w, s);
|
||||
|
||||
ufloat_addmul(w, u, v);
|
||||
|
||||
fmpz_addmul(s, x, y);
|
||||
|
||||
ufloat_get_fmpz(z, w);
|
||||
|
||||
if (fmpz_cmpabs(z, s) < 0)
|
||||
{
|
||||
printf("fail!\n");
|
||||
printf("x = "); fmpz_print(x); printf("\n\n");
|
||||
printf("y = "); fmpz_print(y); printf("\n\n");
|
||||
printf("s = "); fmpz_print(s); printf("\n\n");
|
||||
printf("z = "); fmpz_print(z); printf("\n\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (FLINT_BIT_COUNT(w->man) != UFLOAT_PREC)
|
||||
{
|
||||
printf("wrong number of bits!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
fmpz_clear(x);
|
||||
fmpz_clear(y);
|
||||
fmpz_clear(s);
|
||||
fmpz_clear(z);
|
||||
}
|
||||
|
||||
flint_randclear(state);
|
||||
_fmpz_cleanup();
|
||||
printf("PASS\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
87
ufloat/test/t-div.c
Normal file
87
ufloat/test/t-div.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of ARB.
|
||||
|
||||
ARB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ARB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ARB; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "ufloat.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
long iter;
|
||||
flint_rand_t state;
|
||||
|
||||
printf("div....");
|
||||
fflush(stdout);
|
||||
|
||||
flint_randinit(state);
|
||||
|
||||
for (iter = 0; iter < 1000000; iter++)
|
||||
{
|
||||
fmpz_t x, y, xy, z;
|
||||
ufloat_t u, v, w;
|
||||
|
||||
fmpz_init(x);
|
||||
fmpz_init(y);
|
||||
fmpz_init(xy);
|
||||
fmpz_init(z);
|
||||
|
||||
fmpz_randtest_not_zero(x, state, 1 + n_randint(state, 500));
|
||||
fmpz_randtest_not_zero(y, state, 1 + n_randint(state, 500));
|
||||
|
||||
ufloat_set_fmpz(u, x);
|
||||
ufloat_set_fmpz_lower(v, y);
|
||||
|
||||
ufloat_div(w, u, v);
|
||||
|
||||
fmpz_cdiv_q(xy, x, y);
|
||||
|
||||
ufloat_get_fmpz(z, w);
|
||||
|
||||
if (fmpz_cmpabs(z, xy) < 0)
|
||||
{
|
||||
printf("fail!\n");
|
||||
printf("x = "); fmpz_print(x); printf("\n\n");
|
||||
printf("y = "); fmpz_print(y); printf("\n\n");
|
||||
printf("xy = "); fmpz_print(xy); printf("\n\n");
|
||||
printf("z = "); fmpz_print(z); printf("\n\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (FLINT_BIT_COUNT(w->man) != UFLOAT_PREC)
|
||||
{
|
||||
printf("wrong number of bits!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
fmpz_clear(x);
|
||||
fmpz_clear(y);
|
||||
fmpz_clear(xy);
|
||||
fmpz_clear(z);
|
||||
}
|
||||
|
||||
flint_randclear(state);
|
||||
_fmpz_cleanup();
|
||||
printf("PASS\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
85
ufloat/test/t-log.c
Normal file
85
ufloat/test/t-log.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of ARB.
|
||||
|
||||
ARB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ARB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ARB; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include <mpfr.h>
|
||||
#include "ufloat.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
long iter;
|
||||
flint_rand_t state;
|
||||
|
||||
printf("log....");
|
||||
fflush(stdout);
|
||||
|
||||
flint_randinit(state);
|
||||
|
||||
for (iter = 0; iter < 1000000; iter++)
|
||||
{
|
||||
mpfr_t x, y, z;
|
||||
ufloat_t u, v;
|
||||
|
||||
if (n_randint(state, 2))
|
||||
ufloat_randtest(u, state, 10);
|
||||
else
|
||||
ufloat_randtest(u, state, 1L << 30);
|
||||
|
||||
mpfr_init2(x, FLINT_BITS);
|
||||
mpfr_init2(y, FLINT_BITS);
|
||||
mpfr_init2(z, FLINT_BITS);
|
||||
|
||||
ufloat_log(v, u);
|
||||
|
||||
ufloat_get_mpfr(x, u);
|
||||
ufloat_get_mpfr(y, v);
|
||||
|
||||
mpfr_log(z, x, MPFR_RNDU);
|
||||
|
||||
if ((FLINT_BIT_COUNT(v->man) != UFLOAT_PREC) && (v->man != 0))
|
||||
{
|
||||
printf("wrong number of bits!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (mpfr_cmp(z, y) > 0)
|
||||
{
|
||||
printf("fail!\n");
|
||||
printf("x = "); mpfr_printf("%.20Rg", x); printf("\n\n");
|
||||
printf("y = "); mpfr_printf("%.20Rg", y); printf("\n\n");
|
||||
printf("z = "); mpfr_printf("%.20Rg", z); printf("\n\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
mpfr_clear(x);
|
||||
mpfr_clear(y);
|
||||
mpfr_clear(z);
|
||||
}
|
||||
|
||||
flint_randclear(state);
|
||||
mpfr_free_cache();
|
||||
printf("PASS\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
87
ufloat/test/t-mul.c
Normal file
87
ufloat/test/t-mul.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of ARB.
|
||||
|
||||
ARB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ARB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ARB; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "ufloat.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
long iter;
|
||||
flint_rand_t state;
|
||||
|
||||
printf("mul....");
|
||||
fflush(stdout);
|
||||
|
||||
flint_randinit(state);
|
||||
|
||||
for (iter = 0; iter < 1000000; iter++)
|
||||
{
|
||||
fmpz_t x, y, xy, z;
|
||||
ufloat_t u, v, w;
|
||||
|
||||
fmpz_init(x);
|
||||
fmpz_init(y);
|
||||
fmpz_init(xy);
|
||||
fmpz_init(z);
|
||||
|
||||
fmpz_randtest_not_zero(x, state, 1 + n_randint(state, 500));
|
||||
fmpz_randtest_not_zero(y, state, 1 + n_randint(state, 500));
|
||||
|
||||
ufloat_set_fmpz(u, x);
|
||||
ufloat_set_fmpz(v, y);
|
||||
|
||||
ufloat_mul(w, u, v);
|
||||
|
||||
fmpz_mul(xy, x, y);
|
||||
|
||||
ufloat_get_fmpz(z, w);
|
||||
|
||||
if (fmpz_cmpabs(z, xy) < 0)
|
||||
{
|
||||
printf("fail!\n");
|
||||
printf("x = "); fmpz_print(x); printf("\n\n");
|
||||
printf("y = "); fmpz_print(y); printf("\n\n");
|
||||
printf("xy = "); fmpz_print(xy); printf("\n\n");
|
||||
printf("z = "); fmpz_print(z); printf("\n\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (FLINT_BIT_COUNT(w->man) != UFLOAT_PREC)
|
||||
{
|
||||
printf("wrong number of bits!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
fmpz_clear(x);
|
||||
fmpz_clear(y);
|
||||
fmpz_clear(xy);
|
||||
fmpz_clear(z);
|
||||
}
|
||||
|
||||
flint_randclear(state);
|
||||
_fmpz_cleanup();
|
||||
printf("PASS\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
80
ufloat/test/t-set_ll_2exp.c
Normal file
80
ufloat/test/t-set_ll_2exp.c
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of ARB.
|
||||
|
||||
ARB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ARB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ARB; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "ufloat.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
long iter;
|
||||
flint_rand_t state;
|
||||
|
||||
printf("set_ll_2exp....");
|
||||
fflush(stdout);
|
||||
|
||||
flint_randinit(state);
|
||||
|
||||
for (iter = 0; iter < 100000; iter++)
|
||||
{
|
||||
ufloat_t u;
|
||||
mp_limb_t hi, lo;
|
||||
fmpz_t a, b;
|
||||
long exp;
|
||||
|
||||
hi = n_randtest(state);
|
||||
lo = n_randtest(state);
|
||||
exp = n_randint(state, 200);
|
||||
|
||||
ufloat_set_ll_2exp(u, hi, lo, exp);
|
||||
|
||||
fmpz_init(a);
|
||||
fmpz_init(b);
|
||||
|
||||
fmpz_set_ui(a, hi);
|
||||
fmpz_mul_2exp(a, a, FLINT_BITS);
|
||||
fmpz_add_ui(a, a, lo);
|
||||
fmpz_mul_2exp(a, a, exp);
|
||||
|
||||
ufloat_get_fmpz(b, u);
|
||||
|
||||
if (fmpz_cmp(a, b) > 0 || fmpz_bits(b) > fmpz_bits(a) + 1)
|
||||
{
|
||||
printf("fail!\n");
|
||||
printf("hi = %lu\n", hi);
|
||||
printf("lo = %lu\n", lo);
|
||||
printf("exp = %ld\n", exp);
|
||||
printf("u = "); ufloat_print(u); printf("\n\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
fmpz_clear(a);
|
||||
fmpz_clear(b);
|
||||
}
|
||||
|
||||
flint_randclear(state);
|
||||
_fmpz_cleanup();
|
||||
printf("PASS\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
67
ufloat/test/t-set_mpfr.c
Normal file
67
ufloat/test/t-set_mpfr.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of ARB.
|
||||
|
||||
ARB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ARB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ARB; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "ufloat.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
long iter;
|
||||
flint_rand_t state;
|
||||
|
||||
printf("set_mpfr....");
|
||||
fflush(stdout);
|
||||
|
||||
flint_randinit(state);
|
||||
|
||||
/* Exact roundtrip */
|
||||
for (iter = 0; iter < 100000; iter++)
|
||||
{
|
||||
ufloat_t u, v;
|
||||
mpfr_t x;
|
||||
|
||||
mpfr_init2(x, UFLOAT_PREC);
|
||||
|
||||
ufloat_randtest(u, state, 10);
|
||||
|
||||
ufloat_get_mpfr(x, u);
|
||||
ufloat_set_mpfr(v, x);
|
||||
|
||||
if (!ufloat_equal(u, v))
|
||||
{
|
||||
printf("fail!\n");
|
||||
printf("u = "); ufloat_print(u); printf("\n\n");
|
||||
printf("v = "); ufloat_print(v); printf("\n\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
mpfr_clear(x);
|
||||
}
|
||||
|
||||
flint_randclear(state);
|
||||
_fmpz_cleanup();
|
||||
printf("PASS\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
98
ufloat/test/t-sub.c
Normal file
98
ufloat/test/t-sub.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*=============================================================================
|
||||
|
||||
This file is part of ARB.
|
||||
|
||||
ARB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ARB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with ARB; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
=============================================================================*/
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (C) 2012 Fredrik Johansson
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
#include "ufloat.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
long iter;
|
||||
flint_rand_t state;
|
||||
|
||||
printf("sub....");
|
||||
fflush(stdout);
|
||||
|
||||
flint_randinit(state);
|
||||
|
||||
for (iter = 0; iter < 1000000; iter++)
|
||||
{
|
||||
fmpz_t x, y, xy, z;
|
||||
ufloat_t u, v, w;
|
||||
|
||||
fmpz_init(x);
|
||||
fmpz_init(y);
|
||||
fmpz_init(xy);
|
||||
fmpz_init(z);
|
||||
|
||||
fmpz_randtest_not_zero(x, state, 1 + n_randint(state, 500));
|
||||
fmpz_randtest_not_zero(y, state, 1 + n_randint(state, 500));
|
||||
|
||||
fmpz_abs(x, x);
|
||||
fmpz_abs(y, y);
|
||||
|
||||
if (fmpz_cmp(x, y) >= 0)
|
||||
{
|
||||
ufloat_set_fmpz(u, x);
|
||||
ufloat_set_fmpz_lower(v, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
ufloat_set_fmpz_lower(u, x);
|
||||
ufloat_set_fmpz(v, y);
|
||||
}
|
||||
|
||||
ufloat_sub(w, u, v);
|
||||
fmpz_sub(xy, x, y);
|
||||
|
||||
ufloat_get_fmpz(z, w);
|
||||
|
||||
if (fmpz_cmpabs(z, xy) < 0)
|
||||
{
|
||||
printf("fail!\n");
|
||||
printf("x = "); fmpz_print(x); printf("\n\n");
|
||||
printf("y = "); fmpz_print(y); printf("\n\n");
|
||||
printf("xy = "); fmpz_print(xy); printf("\n\n");
|
||||
printf("z = "); fmpz_print(z); printf("\n\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (!(FLINT_BIT_COUNT(w->man) == UFLOAT_PREC ||
|
||||
w->man == 0))
|
||||
{
|
||||
printf("wrong number of bits!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
fmpz_clear(x);
|
||||
fmpz_clear(y);
|
||||
fmpz_clear(xy);
|
||||
fmpz_clear(z);
|
||||
}
|
||||
|
||||
flint_randclear(state);
|
||||
_fmpz_cleanup();
|
||||
printf("PASS\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
Loading…
Add table
Reference in a new issue