zeta.c revision 1.1.1.3
1/* mpfr_zeta -- compute the Riemann Zeta function
2
3Copyright 2003-2018 Free Software Foundation, Inc.
4Contributed by the AriC and Caramba projects, INRIA.
5
6This file is part of the GNU MPFR Library.
7
8The GNU MPFR Library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as published by
10the Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
12
13The GNU MPFR Library is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16License for more details.
17
18You should have received a copy of the GNU Lesser General Public License
19along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23#include <float.h> /* for DBL_MAX */
24
25#define MPFR_NEED_LONGLONG_H
26#include "mpfr-impl.h"
27
28/*
29   Parameters:
30   s - the input floating-point number
31   n, p - parameters from the algorithm
32   tc - an array of p floating-point numbers tc[1]..tc[p]
33   Output:
34   b is the result, i.e.
35   sum(tc[i]*product((s+2j)*(s+2j-1)/n^2,j=1..i-1), i=1..p)*s*n^(-s-1)
36*/
37static void
38mpfr_zeta_part_b (mpfr_t b, mpfr_srcptr s, int n, int p, mpfr_t *tc)
39{
40  mpfr_t s1, d, u;
41  unsigned long n2;
42  int l, t;
43  MPFR_GROUP_DECL (group);
44
45  if (p == 0)
46    {
47      MPFR_SET_ZERO (b);
48      MPFR_SET_POS (b);
49      return;
50    }
51
52  n2 = n * n;
53  MPFR_GROUP_INIT_3 (group, MPFR_PREC (b), s1, d, u);
54
55  /* t equals 2p-2, 2p-3, ... ; s1 equals s+t */
56  t = 2 * p - 2;
57  mpfr_set (d, tc[p], MPFR_RNDN);
58  for (l = 1; l < p; l++)
59    {
60      mpfr_add_ui (s1, s, t, MPFR_RNDN); /* s + (2p-2l) */
61      mpfr_mul (d, d, s1, MPFR_RNDN);
62      t = t - 1;
63      mpfr_add_ui (s1, s, t, MPFR_RNDN); /* s + (2p-2l-1) */
64      mpfr_mul (d, d, s1, MPFR_RNDN);
65      t = t - 1;
66      mpfr_div_ui (d, d, n2, MPFR_RNDN);
67      mpfr_add (d, d, tc[p-l], MPFR_RNDN);
68      /* since s is positive and the tc[i] have alternate signs,
69         the following is unlikely */
70      if (MPFR_UNLIKELY (mpfr_cmpabs (d, tc[p-l]) > 0))
71        mpfr_set (d, tc[p-l], MPFR_RNDN);
72    }
73  mpfr_mul (d, d, s, MPFR_RNDN);
74  mpfr_add (s1, s, __gmpfr_one, MPFR_RNDN);
75  mpfr_neg (s1, s1, MPFR_RNDN);
76  mpfr_ui_pow (u, n, s1, MPFR_RNDN);
77  mpfr_mul (b, d, u, MPFR_RNDN);
78
79  MPFR_GROUP_CLEAR (group);
80}
81
82/* Input: p - an integer
83   Output: fills tc[1..p], tc[i] = bernoulli(2i)/(2i)!
84   tc[1]=1/12, tc[2]=-1/720, tc[3]=1/30240, ...
85*/
86static void
87mpfr_zeta_c (int p, mpfr_t *tc)
88{
89  mpfr_t d;
90  int k, l;
91
92  if (p > 0)
93    {
94      mpfr_init2 (d, MPFR_PREC (tc[1]));
95      mpfr_div_ui (tc[1], __gmpfr_one, 12, MPFR_RNDN);
96      for (k = 2; k <= p; k++)
97        {
98          mpfr_set_ui (d, k-1, MPFR_RNDN);
99          mpfr_div_ui (d, d, 12*k+6, MPFR_RNDN);
100          for (l=2; l < k; l++)
101            {
102              mpfr_div_ui (d, d, 4*(2*k-2*l+3)*(2*k-2*l+2), MPFR_RNDN);
103              mpfr_add (d, d, tc[l], MPFR_RNDN);
104            }
105          mpfr_div_ui (tc[k], d, 24, MPFR_RNDN);
106          MPFR_CHANGE_SIGN (tc[k]);
107        }
108      mpfr_clear (d);
109    }
110}
111
112/* Input: s - a floating-point number
113          n - an integer
114   Output: sum - a floating-point number approximating sum(1/i^s, i=1..n-1) */
115static void
116mpfr_zeta_part_a (mpfr_t sum, mpfr_srcptr s, int n)
117{
118  mpfr_t u, s1;
119  int i;
120  MPFR_GROUP_DECL (group);
121
122  MPFR_GROUP_INIT_2 (group, MPFR_PREC (sum), u, s1);
123
124  mpfr_neg (s1, s, MPFR_RNDN);
125  mpfr_ui_pow (u, n, s1, MPFR_RNDN);
126  mpfr_div_2ui (u, u, 1, MPFR_RNDN);
127  mpfr_set (sum, u, MPFR_RNDN);
128  for (i=n-1; i>1; i--)
129    {
130      mpfr_ui_pow (u, i, s1, MPFR_RNDN);
131      mpfr_add (sum, sum, u, MPFR_RNDN);
132    }
133  mpfr_add (sum, sum, __gmpfr_one, MPFR_RNDN);
134
135  MPFR_GROUP_CLEAR (group);
136}
137
138/* Input: s - a floating-point number >= 1/2.
139          rnd_mode - a rounding mode.
140          Assumes s is neither NaN nor Infinite.
141   Output: z - Zeta(s) rounded to the precision of z with direction rnd_mode
142*/
143static int
144mpfr_zeta_pos (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
145{
146  mpfr_t b, c, z_pre, f, s1;
147  double beta, sd, dnep;
148  mpfr_t *tc1;
149  mpfr_prec_t precz, precs, d, dint;
150  int p, n, l, add;
151  int inex;
152  MPFR_GROUP_DECL (group);
153  MPFR_ZIV_DECL (loop);
154
155  MPFR_ASSERTD (MPFR_IS_POS (s) && MPFR_GET_EXP (s) >= 0);
156
157  precz = MPFR_PREC (z);
158  precs = MPFR_PREC (s);
159
160  /* Zeta(x) = 1+1/2^x+1/3^x+1/4^x+1/5^x+O(1/6^x)
161     so with 2^(EXP(x)-1) <= x < 2^EXP(x)
162     So for x > 2^3, k^x > k^8, so 2/k^x < 2/k^8
163     Zeta(x) = 1 + 1/2^x*(1+(2/3)^x+(2/4)^x+...)
164             = 1 + 1/2^x*(1+sum((2/k)^x,k=3..infinity))
165            <= 1 + 1/2^x*(1+sum((2/k)^8,k=3..infinity))
166     And sum((2/k)^8,k=3..infinity) = -257+128*Pi^8/4725 ~= 0.0438035
167     So Zeta(x) <= 1 + 1/2^x*2 for x >= 8
168     The error is < 2^(-x+1) <= 2^(-2^(EXP(x)-1)+1) */
169  if (MPFR_GET_EXP (s) > 3)
170    {
171      mpfr_exp_t err;
172      err = MPFR_GET_EXP (s) - 1;
173      if (err > (mpfr_exp_t) (sizeof (mpfr_exp_t)*CHAR_BIT-2))
174        err = MPFR_EMAX_MAX;
175      else
176        err = ((mpfr_exp_t)1) << err;
177      err = 1 - (-err+1); /* GET_EXP(one) - (-err+1) = err :) */
178      MPFR_FAST_COMPUTE_IF_SMALL_INPUT (z, __gmpfr_one, err, 0, 1,
179                                        rnd_mode, {});
180    }
181
182  d = precz + MPFR_INT_CEIL_LOG2(precz) + 10;
183
184  /* we want that s1 = s-1 is exact, i.e. we should have PREC(s1) >= EXP(s) */
185  dint = (mpfr_uexp_t) MPFR_GET_EXP (s);
186  mpfr_init2 (s1, MAX (precs, dint));
187  inex = mpfr_sub (s1, s, __gmpfr_one, MPFR_RNDN);
188  MPFR_ASSERTD (inex == 0);
189
190  /* case s=1 should have already been handled */
191  MPFR_ASSERTD (!MPFR_IS_ZERO (s1));
192
193  MPFR_GROUP_INIT_4 (group, MPFR_PREC_MIN, b, c, z_pre, f);
194
195  MPFR_ZIV_INIT (loop, d);
196  for (;;)
197    {
198      /* Principal loop: we compute, in z_pre,
199         an approximation of Zeta(s), that we send to can_round */
200      if (MPFR_GET_EXP (s1) <= -(mpfr_exp_t) ((mpfr_prec_t) (d-3)/2))
201        /* Branch 1: when s-1 is very small, one
202           uses the approximation Zeta(s)=1/(s-1)+gamma,
203           where gamma is Euler's constant */
204        {
205          dint = MAX (d + 3, precs);
206          /* branch 1, with internal precision dint */
207          MPFR_GROUP_REPREC_4 (group, dint, b, c, z_pre, f);
208          mpfr_div (z_pre, __gmpfr_one, s1, MPFR_RNDN);
209          mpfr_const_euler (f, MPFR_RNDN);
210          mpfr_add (z_pre, z_pre, f, MPFR_RNDN);
211        }
212      else /* Branch 2 */
213        {
214          size_t size;
215
216          /* branch 2 */
217          /* Computation of parameters n, p and working precision */
218          dnep = (double) d * LOG2;
219          sd = mpfr_get_d (s, MPFR_RNDN);
220          /* beta = dnep + 0.61 + sd * log (6.2832 / sd);
221             but a larger value is OK */
222#define LOG6dot2832 1.83787940484160805532
223          beta = dnep + 0.61 + sd * (LOG6dot2832 - LOG2 *
224                                     __gmpfr_floor_log2 (sd));
225          if (beta <= 0.0)
226            {
227              p = 0;
228              /* n = 1 + (int) (exp ((dnep - LOG2) / sd)); */
229              n = 1 + (int) __gmpfr_ceil_exp2 ((d - 1.0) / sd);
230            }
231          else
232            {
233              p = 1 + (int) beta / 2;
234              n = 1 + (int) ((sd + 2.0 * (double) p - 1.0) / 6.2832);
235            }
236          /* add = 4 + floor(1.5 * log(d) / log (2)).
237             We should have add >= 10, which is always fulfilled since
238             d = precz + 11 >= 12, thus ceil(log2(d)) >= 4 */
239          add = 4 + (3 * MPFR_INT_CEIL_LOG2 (d)) / 2;
240          MPFR_ASSERTD(add >= 10);
241          dint = d + add;
242          if (dint < precs)
243            dint = precs;
244
245          /* internal precision is dint */
246
247          size = (p + 1) * sizeof(mpfr_t);
248          tc1 = (mpfr_t*) mpfr_allocate_func (size);
249          for (l=1; l<=p; l++)
250            mpfr_init2 (tc1[l], dint);
251          MPFR_GROUP_REPREC_4 (group, dint, b, c, z_pre, f);
252
253          /* precision of z is precz */
254
255          /* Computation of the coefficients c_k */
256          mpfr_zeta_c (p, tc1);
257          /* Computation of the 3 parts of the function Zeta. */
258          mpfr_zeta_part_a (z_pre, s, n);
259          mpfr_zeta_part_b (b, s, n, p, tc1);
260          /* s1 = s-1 is already computed above */
261          mpfr_div (c, __gmpfr_one, s1, MPFR_RNDN);
262          mpfr_ui_pow (f, n, s1, MPFR_RNDN);
263          mpfr_div (c, c, f, MPFR_RNDN);
264          mpfr_add (z_pre, z_pre, c, MPFR_RNDN);
265          mpfr_add (z_pre, z_pre, b, MPFR_RNDN);
266          for (l=1; l<=p; l++)
267            mpfr_clear (tc1[l]);
268          mpfr_free_func (tc1, size);
269          /* End branch 2 */
270        }
271
272      if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, d-3, precz, rnd_mode)))
273        break;
274      MPFR_ZIV_NEXT (loop, d);
275    }
276  MPFR_ZIV_FREE (loop);
277
278  inex = mpfr_set (z, z_pre, rnd_mode);
279
280  MPFR_GROUP_CLEAR (group);
281  mpfr_clear (s1);
282
283  return inex;
284}
285
286/* return add = 1 + floor(log(c^3*(13+m1))/log(2))
287   where c = (1+eps)*(1+eps*max(8,m1)),
288   m1 = 1 + max(1/eps,2*sd)*(1+eps),
289   eps = 2^(-precz-14)
290   sd = abs(s-1)
291 */
292static long
293compute_add (mpfr_srcptr s, mpfr_prec_t precz)
294{
295  mpfr_t t, u, m1;
296  long add;
297
298  mpfr_inits2 (64, t, u, m1, (mpfr_ptr) 0);
299  if (mpfr_cmp_ui (s, 1) >= 0)
300    mpfr_sub_ui (t, s, 1, MPFR_RNDU);
301  else
302    mpfr_ui_sub (t, 1, s, MPFR_RNDU);
303  /* now t = sd = abs(s-1), rounded up */
304  mpfr_set_ui_2exp (u, 1, - precz - 14, MPFR_RNDU);
305  /* u = eps */
306  /* since 1/eps = 2^(precz+14), if EXP(sd) >= precz+14, then
307     sd >= 1/2*2^(precz+14) thus 2*sd >= 2^(precz+14) >= 1/eps */
308  if (mpfr_get_exp (t) >= precz + 14)
309    mpfr_mul_2exp (t, t, 1, MPFR_RNDU);
310  else
311    mpfr_set_ui_2exp (t, 1, precz + 14, MPFR_RNDU);
312  /* now t = max(1/eps,2*sd) */
313  mpfr_add_ui (u, u, 1, MPFR_RNDU); /* u = 1+eps, rounded up */
314  mpfr_mul (t, t, u, MPFR_RNDU); /* t = max(1/eps,2*sd)*(1+eps) */
315  mpfr_add_ui (m1, t, 1, MPFR_RNDU);
316  if (mpfr_get_exp (m1) <= 3)
317    mpfr_set_ui (t, 8, MPFR_RNDU);
318  else
319    mpfr_set (t, m1, MPFR_RNDU);
320  /* now t = max(8,m1) */
321  mpfr_div_2exp (t, t, precz + 14, MPFR_RNDU); /* eps*max(8,m1) */
322  mpfr_add_ui (t, t, 1, MPFR_RNDU); /* 1+eps*max(8,m1) */
323  mpfr_mul (t, t, u, MPFR_RNDU); /* t = c */
324  mpfr_add_ui (u, m1, 13, MPFR_RNDU); /* 13+m1 */
325  mpfr_mul (u, u, t, MPFR_RNDU); /* c*(13+m1) */
326  mpfr_sqr (t, t, MPFR_RNDU); /* c^2 */
327  mpfr_mul (u, u, t, MPFR_RNDU); /* c^3*(13+m1) */
328  add = mpfr_get_exp (u);
329  mpfr_clears (t, u, m1, (mpfr_ptr) 0);
330  return add;
331}
332
333/* return in z a lower bound (for rnd = RNDD) or upper bound (for rnd = RNDU)
334   of |zeta(s)|/2, using:
335   log(|zeta(s)|/2) = (s-1)*log(2*Pi) + lngamma(1-s)
336   + log(|sin(Pi*s/2)| * zeta(1-s)).
337   Assumes s < 1/2 and s1 = 1-s exactly, thus s1 > 1/2.
338   y and p are temporary variables.
339   At input, p is Pi rounded down.
340   The comments in the code are for rnd = RNDD. */
341static void
342mpfr_reflection_overflow (mpfr_t z, mpfr_t s1, const mpfr_t s, mpfr_t y,
343                          mpfr_t p, mpfr_rnd_t rnd)
344{
345  mpz_t sint;
346
347  MPFR_ASSERTD (rnd == MPFR_RNDD || rnd == MPFR_RNDU);
348
349  /* Since log is increasing, we want lower bounds on |sin(Pi*s/2)| and
350     zeta(1-s). */
351  mpz_init (sint);
352  mpfr_get_z (sint, s, MPFR_RNDD); /* sint = floor(s) */
353  /* We first compute a lower bound of |sin(Pi*s/2)|, which is a periodic
354     function of period 2. Thus:
355     if 2k < s < 2k+1, then |sin(Pi*s/2)| is increasing;
356     if 2k-1 < s < 2k, then |sin(Pi*s/2)| is decreasing.
357     These cases are distinguished by testing bit 0 of floor(s) as if
358     represented in two's complement (or equivalently, as an unsigned
359     integer mod 2):
360     0: sint = 0 mod 2, thus 2k < s < 2k+1 and |sin(Pi*s/2)| is increasing;
361     1: sint = 1 mod 2, thus 2k-1 < s < 2k and |sin(Pi*s/2)| is decreasing.
362     Let's recall that the comments are for rnd = RNDD. */
363  if (mpz_tstbit (sint, 0) == 0) /* |sin(Pi*s/2)| is increasing: round down
364                                    Pi*s to get a lower bound. */
365    {
366      mpfr_mul (y, p, s, rnd);
367      if (rnd == MPFR_RNDD)
368        mpfr_nextabove (p); /* we will need p rounded above afterwards */
369    }
370  else /* |sin(Pi*s/2)| is decreasing: round up Pi*s to get a lower bound. */
371    {
372      if (rnd == MPFR_RNDD)
373        mpfr_nextabove (p);
374      mpfr_mul (y, p, s, MPFR_INVERT_RND(rnd));
375    }
376  mpfr_div_2ui (y, y, 1, MPFR_RNDN); /* exact, rounding mode doesn't matter */
377  /* The rounding direction of sin depends on its sign. We have:
378     if -4k-2 < s < -4k, then -2k-1 < s/2 < -2k, thus sin(Pi*s/2) < 0;
379     if -4k < s < -4k+2, then -2k < s/2 < -2k+1, thus sin(Pi*s/2) > 0.
380     These cases are distinguished by testing bit 1 of floor(s) as if
381     represented in two's complement (or equivalently, as an unsigned
382     integer mod 4):
383     0: sint = {0,1} mod 4, thus -2k < s/2 < -2k+1 and sin(Pi*s/2) > 0;
384     1: sint = {2,3} mod 4, thus -2k-1 < s/2 < -2k and sin(Pi*s/2) < 0.
385     Let's recall that the comments are for rnd = RNDD. */
386  if (mpz_tstbit (sint, 1) == 0) /* -2k < s/2 < -2k+1; sin(Pi*s/2) > 0 */
387    {
388      /* Round sin down to get a lower bound of |sin(Pi*s/2)|. */
389      mpfr_sin (y, y, rnd);
390    }
391  else /* -2k-1 < s/2 < -2k; sin(Pi*s/2) < 0 */
392    {
393      /* Round sin up to get a lower bound of |sin(Pi*s/2)|. */
394      mpfr_sin (y, y, MPFR_INVERT_RND(rnd));
395      mpfr_abs (y, y, MPFR_RNDN); /* exact, rounding mode doesn't matter */
396    }
397  mpz_clear (sint);
398  /* now y <= |sin(Pi*s/2)| when rnd=RNDD, y >= |sin(Pi*s/2)| when rnd=RNDU */
399  mpfr_zeta_pos (z, s1, rnd); /* zeta(1-s) */
400  mpfr_mul (z, z, y, rnd);
401  /* now z <= |sin(Pi*s/2)|*zeta(1-s) */
402  mpfr_log (z, z, rnd);
403  /* now z <= log(|sin(Pi*s/2)|*zeta(1-s)) */
404  mpfr_lngamma (y, s1, rnd);
405  mpfr_add (z, z, y, rnd);
406  /* z <= lngamma(1-s) + log(|sin(Pi*s/2)|*zeta(1-s)) */
407  /* since s-1 < 0, we want to round log(2*pi) upwards */
408  mpfr_mul_2ui (y, p, 1, MPFR_INVERT_RND(rnd));
409  mpfr_log (y, y, MPFR_INVERT_RND(rnd));
410  mpfr_mul (y, y, s1, MPFR_INVERT_RND(rnd));
411  mpfr_sub (z, z, y, rnd);
412  mpfr_exp (z, z, rnd);
413  if (rnd == MPFR_RNDD)
414    mpfr_nextbelow (p); /* restore original p */
415}
416
417int
418mpfr_zeta (mpfr_t z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
419{
420  mpfr_t z_pre, s1, y, p;
421  long add;
422  mpfr_prec_t precz, prec1, precs, precs1;
423  int inex;
424  MPFR_GROUP_DECL (group);
425  MPFR_ZIV_DECL (loop);
426  MPFR_SAVE_EXPO_DECL (expo);
427
428  MPFR_LOG_FUNC (
429    ("s[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (s), mpfr_log_prec, s, rnd_mode),
430    ("z[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (z), mpfr_log_prec, z, inex));
431
432  /* Zero, Nan or Inf ? */
433  if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (s)))
434    {
435      if (MPFR_IS_NAN (s))
436        {
437          MPFR_SET_NAN (z);
438          MPFR_RET_NAN;
439        }
440      else if (MPFR_IS_INF (s))
441        {
442          if (MPFR_IS_POS (s))
443            return mpfr_set_ui (z, 1, MPFR_RNDN); /* Zeta(+Inf) = 1 */
444          MPFR_SET_NAN (z); /* Zeta(-Inf) = NaN */
445          MPFR_RET_NAN;
446        }
447      else /* s iz zero */
448        {
449          MPFR_ASSERTD (MPFR_IS_ZERO (s));
450          return mpfr_set_si_2exp (z, -1, -1, rnd_mode);
451        }
452    }
453
454  /* s is neither Nan, nor Inf, nor Zero */
455
456  /* check tiny s: we have zeta(s) = -1/2 - 1/2 log(2 Pi) s + ... around s=0,
457     and for |s| <= 2^(-4), we have |zeta(s) + 1/2| <= |s|.
458     EXP(s) + 1 < -PREC(z) is a sufficient condition to be able to round
459     correctly, for any PREC(z) >= 1 (see algorithms.tex for details). */
460  if (MPFR_GET_EXP (s) + 1 < - (mpfr_exp_t) MPFR_PREC(z))
461    {
462      int signs = MPFR_SIGN(s);
463
464      MPFR_SAVE_EXPO_MARK (expo);
465      mpfr_set_si_2exp (z, -1, -1, rnd_mode); /* -1/2 */
466      if (rnd_mode == MPFR_RNDA)
467        rnd_mode = MPFR_RNDD; /* the result is around -1/2, thus negative */
468      if ((rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDZ) && signs < 0)
469        {
470          mpfr_nextabove (z); /* z = -1/2 + epsilon */
471          inex = 1;
472        }
473      else if (rnd_mode == MPFR_RNDD && signs > 0)
474        {
475          mpfr_nextbelow (z); /* z = -1/2 - epsilon */
476          inex = -1;
477        }
478      else
479        {
480          if (rnd_mode == MPFR_RNDU) /* s > 0: z = -1/2 */
481            inex = 1;
482          else if (rnd_mode == MPFR_RNDD)
483            inex = -1;              /* s < 0: z = -1/2 */
484          else /* (MPFR_RNDZ and s > 0) or MPFR_RNDN: z = -1/2 */
485            inex = (signs > 0) ? 1 : -1;
486        }
487      MPFR_SAVE_EXPO_FREE (expo);
488      return mpfr_check_range (z, inex, rnd_mode);
489    }
490
491  /* Check for case s= -2n */
492  if (MPFR_IS_NEG (s))
493    {
494      mpfr_t tmp;
495      tmp[0] = *s;
496      MPFR_EXP (tmp) = MPFR_GET_EXP (s) - 1;
497      if (mpfr_integer_p (tmp))
498        {
499          MPFR_SET_ZERO (z);
500          MPFR_SET_POS (z);
501          MPFR_RET (0);
502        }
503    }
504
505  /* Check for case s=1 before changing the exponent range */
506  if (mpfr_cmp (s, __gmpfr_one) == 0)
507    {
508      MPFR_SET_INF (z);
509      MPFR_SET_POS (z);
510      MPFR_SET_DIVBY0 ();
511      MPFR_RET (0);
512    }
513
514  MPFR_SAVE_EXPO_MARK (expo);
515
516  /* Compute Zeta */
517  if (MPFR_IS_POS (s) && MPFR_GET_EXP (s) >= 0) /* Case s >= 1/2 */
518    inex = mpfr_zeta_pos (z, s, rnd_mode);
519  else /* use reflection formula
520          zeta(s) = 2^s*Pi^(s-1)*sin(Pi*s/2)*gamma(1-s)*zeta(1-s) */
521    {
522      int overflow = 0;
523
524      precz = MPFR_PREC (z);
525      precs = MPFR_PREC (s);
526
527      /* Precision precs1 needed to represent 1 - s, and s + 2,
528         without any truncation */
529      precs1 = precs + 2 + MAX (0, - MPFR_GET_EXP (s));
530      /* Precision prec1 is the precision on elementary computations;
531         it ensures a final precision prec1 - add for zeta(s) */
532      add = compute_add (s, precz);
533      prec1 = precz + add;
534      /* FIXME: To avoid that the working precision (prec1) depends on the
535         input precision, one would need to take into account the error made
536         when s1 is not exactly 1-s when computing zeta(s1) and gamma(s1)
537         below, and also in the case y=Inf (i.e. when gamma(s1) overflows).
538         Make sure that underflows do not occur in intermediate computations.
539         Due to the limited precision, they are probably not possible
540         in practice; add some MPFR_ASSERTN's to be sure that problems
541         do not remain undetected? */
542      prec1 = MAX (prec1, precs1) + 10;
543
544      MPFR_GROUP_INIT_4 (group, prec1, z_pre, s1, y, p);
545      MPFR_ZIV_INIT (loop, prec1);
546      for (;;)
547        {
548          mpfr_exp_t ey;
549          mpfr_t z_up;
550
551          mpfr_const_pi (p, MPFR_RNDD); /* p is Pi */
552
553          mpfr_sub (s1, __gmpfr_one, s, MPFR_RNDN); /* s1 = 1-s */
554          mpfr_gamma (y, s1, MPFR_RNDN);          /* gamma(1-s) */
555          if (MPFR_IS_INF (y)) /* zeta(s) < 0 for -4k-2 < s < -4k,
556                                  zeta(s) > 0 for -4k < s < -4k+2 */
557            {
558              /* FIXME: An overflow in gamma(s1) does not imply that
559                 zeta(s) will overflow. A solution:
560                 1. Compute
561                   log(|zeta(s)|/2) = (s-1)*log(2*pi) + lngamma(1-s)
562                     + log(abs(sin(Pi*s/2)) * zeta(1-s))
563                 (possibly sharing computations with the normal case)
564                 with a rather good accuracy (see (2)).
565                 Memorize the sign of sin(...) for the final sign.
566                 2. Take the exponential, ~= |zeta(s)|/2. If there is an
567                 overflow, then this means an overflow on the final result
568                 (due to the multiplication by 2, which has not been done
569                 yet).
570                 3. Ziv test.
571                 4. Correct the sign from the sign of sin(...).
572                 5. Round then multiply by 2. Here, an overflow in either
573                 operation means a real overflow. */
574              mpfr_reflection_overflow (z_pre, s1, s, y, p, MPFR_RNDD);
575              /* z_pre is a lower bound of |zeta(s)|/2, thus if it overflows,
576                 or has exponent emax, then |zeta(s)| overflows too. */
577              if (MPFR_IS_INF (z_pre) || MPFR_GET_EXP(z_pre) == __gmpfr_emax)
578                { /* determine the sign of overflow */
579                  mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */
580                  mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */
581                  overflow = (mpfr_cmp_si_2exp (s1, -1, -1) > 0) ? -1 : 1;
582                  break;
583                }
584              else /* EXP(z_pre) < __gmpfr_emax */
585                {
586                  int ok = 0;
587                  mpfr_t z_down;
588                  mpfr_init2 (z_up, mpfr_get_prec (z_pre));
589                  mpfr_reflection_overflow (z_up, s1, s, y, p, MPFR_RNDU);
590                  /* if the lower approximation z_pre does not overflow, but
591                     z_up does, we need more precision */
592                  if (MPFR_IS_INF (z_up) || MPFR_GET_EXP(z_up) == __gmpfr_emax)
593                    goto next_loop;
594                  /* check if z_pre and z_up round to the same number */
595                  mpfr_init2 (z_down, precz);
596                  mpfr_set (z_down, z_pre, rnd_mode);
597                  /* Note: it might be that EXP(z_down) = emax here, in that
598                     case we will have overflow below when we multiply by 2 */
599                  mpfr_prec_round (z_up, precz, rnd_mode);
600                  ok = mpfr_cmp (z_down, z_up) == 0;
601                  mpfr_clear (z_up);
602                  mpfr_clear (z_down);
603                  if (ok)
604                    {
605                      /* get correct sign and multiply by 2 */
606                      mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */
607                      mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */
608                      if (mpfr_cmp_si_2exp (s1, -1, -1) > 0)
609                        mpfr_neg (z_pre, z_pre, rnd_mode);
610                      mpfr_mul_2ui (z_pre, z_pre, 1, rnd_mode);
611                      break;
612                    }
613                  else
614                    goto next_loop;
615                }
616            }
617          mpfr_zeta_pos (z_pre, s1, MPFR_RNDN);   /* zeta(1-s)  */
618          mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);  /* gamma(1-s)*zeta(1-s) */
619
620          /* multiply z_pre by 2^s*Pi^(s-1) where p=Pi, s1=1-s */
621          mpfr_mul_2ui (y, p, 1, MPFR_RNDN);      /* 2*Pi */
622          mpfr_neg (s1, s1, MPFR_RNDN);           /* s-1 */
623          mpfr_pow (y, y, s1, MPFR_RNDN);         /* (2*Pi)^(s-1) */
624          mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);
625          mpfr_mul_2ui (z_pre, z_pre, 1, MPFR_RNDN);
626
627          /* multiply z_pre by sin(Pi*s/2) */
628          mpfr_mul (y, s, p, MPFR_RNDN);
629          mpfr_div_2ui (p, y, 1, MPFR_RNDN);      /* p = s*Pi/2 */
630          /* FIXME: sinpi will be available, we should replace the mpfr_sin
631             call below by mpfr_sinpi(s/2), where s/2 will be exact.
632             Can mpfr_sin underflow? Moreover, the code below should be
633             improved so that the "if" condition becomes unlikely, e.g.
634             by taking a slightly larger working precision. */
635          mpfr_sin (y, p, MPFR_RNDN);             /* y = sin(Pi*s/2) */
636          ey = MPFR_GET_EXP (y);
637          if (ey < 0) /* take account of cancellation in sin(p) */
638            {
639              mpfr_t t;
640
641              MPFR_ASSERTN (- ey < MPFR_PREC_MAX - prec1);
642              mpfr_init2 (t, prec1 - ey);
643              mpfr_const_pi (t, MPFR_RNDD);
644              mpfr_mul (t, s, t, MPFR_RNDN);
645              mpfr_div_2ui (t, t, 1, MPFR_RNDN);
646              mpfr_sin (y, t, MPFR_RNDN);
647              mpfr_clear (t);
648            }
649          mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);
650
651          if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, prec1 - add, precz,
652                                           rnd_mode)))
653            break;
654
655        next_loop:
656          MPFR_ZIV_NEXT (loop, prec1);
657          MPFR_GROUP_REPREC_4 (group, prec1, z_pre, s1, y, p);
658        }
659      MPFR_ZIV_FREE (loop);
660      if (overflow != 0)
661        {
662          inex = mpfr_overflow (z, rnd_mode, overflow);
663          MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
664        }
665      else
666        inex = mpfr_set (z, z_pre, rnd_mode);
667      MPFR_GROUP_CLEAR (group);
668    }
669
670  MPFR_SAVE_EXPO_FREE (expo);
671  return mpfr_check_range (z, inex, rnd_mode);
672}
673