diff --git a/fmpr.h b/fmpr.h index fde72f73..3692dabe 100644 --- a/fmpr.h +++ b/fmpr.h @@ -734,5 +734,22 @@ fmpr_printd(const fmpr_t x, long digits) mpfr_clear(t); } +static __inline__ void +fmpr_mul_2exp_si(fmpr_t y, const fmpr_t x, long e) +{ + if (e == 0 || fmpr_is_special(x)) + { + fmpr_set(y, x); + } + else + { + fmpz_set(fmpr_manref(y), fmpr_manref(x)); + if (e > 0) + fmpz_add_ui(fmpr_expref(y), fmpr_expref(x), e); + else + fmpz_sub_ui(fmpr_expref(y), fmpr_expref(x), -e); + } +} + #endif diff --git a/fmprb.h b/fmprb.h index 387caeeb..2d1fd77a 100644 --- a/fmprb.h +++ b/fmprb.h @@ -137,6 +137,7 @@ void fmprb_div(fmprb_t z, const fmprb_t x, const fmprb_t y, long prec); void fmprb_div_ui(fmprb_t z, const fmprb_t x, ulong y, long prec); void fmprb_div_si(fmprb_t z, const fmprb_t x, long y, long prec); void fmprb_div_fmpz(fmprb_t z, const fmprb_t x, const fmpz_t y, long prec); +void fmprb_fmpz_div_fmpz(fmprb_t y, const fmpz_t num, const fmpz_t den, long prec); void fmprb_mul(fmprb_t z, const fmprb_t x, const fmprb_t y, long prec); void fmprb_mul_ui(fmprb_t z, const fmprb_t x, ulong y, long prec); @@ -157,6 +158,7 @@ void fmprb_submul_ui(fmprb_t z, const fmprb_t x, ulong y, long prec); void fmprb_submul_si(fmprb_t z, const fmprb_t x, long y, long prec); void fmprb_submul_fmpz(fmprb_t z, const fmprb_t x, const fmpz_t y, long prec); +void fmprb_pow_ui(fmprb_t y, const fmprb_t b, ulong e, long prec); void fmprb_ui_pow_ui(fmprb_t y, ulong b, ulong e, long prec); void fmprb_si_pow_ui(fmprb_t y, long b, ulong e, long prec); @@ -170,6 +172,8 @@ void fmprb_bin_ui(fmprb_t x, const fmprb_t n, ulong k, long prec); void fmprb_bin_uiui(fmprb_t x, ulong n, ulong k, long prec); void fmprb_const_pi_chudnovsky(fmprb_t x, long prec); +void fmprb_const_pi(fmprb_t x, long prec); + void fmprb_const_euler_brent_mcmillan(fmprb_t res, long prec); void fmprb_const_zeta3_bsplit(fmprb_t x, long prec); @@ -195,5 +199,18 @@ fmprb_printd(const fmprb_t x, long digits) fmpr_printd(fmprb_radref(x), 5); } +static __inline__ void +fmprb_mul_2exp_si(fmprb_t y, const fmprb_t x, long e) +{ + fmpr_mul_2exp_si(fmprb_midref(y), fmprb_midref(x), e); + fmpr_mul_2exp_si(fmprb_radref(y), fmprb_radref(x), e); +} + +static __inline__ void +fmprb_set_fmpq(fmprb_t y, const fmpq_t x, long prec) +{ + fmprb_fmpz_div_fmpz(y, fmpq_numref(x), fmpq_denref(x), prec); +} + #endif diff --git a/fmprb/const_pi.c b/fmprb/const_pi.c new file mode 100644 index 00000000..dc8b5243 --- /dev/null +++ b/fmprb/const_pi.c @@ -0,0 +1,46 @@ +/*============================================================================= + + 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 "fmprb.h" + +/* TODO: make threadsafe; round output */ + +long fmprb_const_pi_cached_prec = 0; +fmprb_t fmprb_const_pi_cache; + +void +fmprb_const_pi(fmprb_t x, long prec) +{ + if (fmprb_const_pi_cached_prec < prec) + { + if (fmprb_const_pi_cached_prec == 0) + fmprb_init(fmprb_const_pi_cache); + + fmprb_const_pi_chudnovsky(fmprb_const_pi_cache, prec); + fmprb_const_pi_cached_prec = prec; + } + + fmprb_set(x, fmprb_const_pi_cache); +} diff --git a/fmprb/div.c b/fmprb/div.c index a2869ee1..bbc10f84 100644 --- a/fmprb/div.c +++ b/fmprb/div.c @@ -118,3 +118,22 @@ fmprb_div_fmpz(fmprb_t z, const fmprb_t x, const fmpz_t y, long prec) fmprb_div(z, x, t, prec); fmprb_clear(t); } + +void +fmprb_fmpz_div_fmpz(fmprb_t y, const fmpz_t num, const fmpz_t den, long prec) +{ + fmpr_t p, q; + long r; + + fmpr_init(p); + fmpr_init(q); + + fmpr_set_fmpz(p, num); + fmpr_set_fmpz(q, den); + + r = fmpr_div(fmprb_midref(y), p, q, prec, FMPR_RND_DOWN); + fmpr_set_error_result(fmprb_radref(y), fmprb_midref(y), r); + + fmpr_clear(p); + fmpr_clear(q); +} diff --git a/fmprb/pow.c b/fmprb/pow.c index 061cc049..76e0acfa 100644 --- a/fmprb/pow.c +++ b/fmprb/pow.c @@ -26,41 +26,52 @@ #include "fmprb.h" void -fmprb_ui_pow_ui(fmprb_t y, ulong b, ulong e, long prec) +fmprb_pow_ui(fmprb_t y, const fmprb_t b, ulong e, long prec) { long i; - if (e <= 1) + if (y == b) { - fmprb_set_ui(y, e == 0 ? 1 : b); + fmprb_t t; + fmprb_init(t); + fmprb_set(t, b); + fmprb_pow_ui(y, t, e, prec); + fmprb_clear(t); return; } - fmprb_set_ui(y, b); + if (e == 0) + { + fmprb_set_ui(y, 1UL); + return; + } + + fmprb_set(y, b); + for (i = FLINT_BIT_COUNT(e) - 2; i >= 0; i--) { fmprb_mul(y, y, y, prec); if (e & (1UL<= 0; i--) - { - fmprb_mul(y, y, y, prec); - if (e & (1UL<