summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--lngamma.c17
2 files changed, 16 insertions, 3 deletions
diff --git a/TODO b/TODO
index fb1192f44..76f58e4f2 100644
--- a/TODO
+++ b/TODO
@@ -237,6 +237,8 @@ New functions to implement:
- mpfr_frexp(mpfr_t rop, mp_exp_t *n, mpfr_t op, mp_rnd_t rnd) suggested by
Steve Kargl <sgk@troutmask.apl.washington.edu> Sun, 7 Aug 2005
+- mpfr_inp_raw, mpfr_out_raw (cf mail "Serialization of mpfr_t" from Alexey
+ and answer from Granlund on mpfr list, May 2007)
##############################################################################
diff --git a/lngamma.c b/lngamma.c
index 9a6d59761..70e81e628 100644
--- a/lngamma.c
+++ b/lngamma.c
@@ -193,7 +193,7 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mp_rnd_t rnd)
w = precy + MPFR_INT_CEIL_LOG2 (precy);
while (1)
{
- w += MPFR_INT_CEIL_LOG2 (w) + 13;
+ w += MPFR_INT_CEIL_LOG2 (w) + 14;
MPFR_ASSERTD(w >= 3);
mpfr_set_prec (s, w);
mpfr_set_prec (t, w);
@@ -228,8 +228,19 @@ GAMMA_FUNC (mpfr_ptr y, mpfr_srcptr z0, mp_rnd_t rnd)
2^(err_s+1)*2^(-w)*|s| since ulp(s) <= 2^(1-w)*|s|.
Now n*2^(-w) can always be written |(1+r)^n-1| for some
|r|<=2^(-w), thus taking n=2^(err_s+1) we see that
- the relative error is bounded by |(1+r)^(2^(err_s+1))-1| */
- err_s ++; /* relative error */
+ |S - s| <= |(1+r)^(2^(err_s+1))-1| * |s|, where S is the
+ true value.
+ In fact if ulp(s) <= ulp(S) the same inequality holds for
+ |S| instead of |s| in the right hand side, i.e., we can
+ write s = (1+r)^(2^(err_s+1)) * S.
+ But if ulp(S) < ulp(s), we need to add one ``bit'' to the error,
+ to get s = (1+r)^(2^(err_s+2)) * S. This is true since with
+ E = n*2^(-w) we have |s - S| <= E * |s|, thus
+ |s - S| <= E/(1-E) * |S|.
+ Now E/(1-E) is bounded by 2E as long as E<=1/2,
+ and 2E can be written (1+r)^(2n)-1 as above.
+ */
+ err_s += 2; /* exponent of relative error */
mpfr_sub_ui (v, z0, 1, GMP_RNDN); /* v = (x-1) * (1+r) */
mpfr_mul (v, v, t, GMP_RNDN); /* v = Pi*(x-1) * (1+r)^3 */