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