1 /* mpfr_zeta -- compute the Riemann Zeta function
2 
3 Copyright 2003-2020 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 /* return add = 1 + floor(log(c^3*(13+m1))/log(2))
304    where c = (1+eps)*(1+eps*max(8,m1)),
305    m1 = 1 + max(1/eps,2*sd)*(1+eps),
306    eps = 2^(-precz-14)
307    sd = abs(s-1)
308  */
309 static long
compute_add(mpfr_srcptr s,mpfr_prec_t precz)310 compute_add (mpfr_srcptr s, mpfr_prec_t precz)
311 {
312   mpfr_t t, u, m1;
313   long add;
314 
315   mpfr_inits2 (64, t, u, m1, (mpfr_ptr) 0);
316   if (mpfr_cmp_ui (s, 1) >= 0)
317     mpfr_sub_ui (t, s, 1, MPFR_RNDU);
318   else
319     mpfr_ui_sub (t, 1, s, MPFR_RNDU);
320   /* now t = sd = abs(s-1), rounded up */
321   mpfr_set_ui_2exp (u, 1, - precz - 14, MPFR_RNDU);
322   /* u = eps */
323   /* since 1/eps = 2^(precz+14), if EXP(sd) >= precz+14, then
324      sd >= 1/2*2^(precz+14) thus 2*sd >= 2^(precz+14) >= 1/eps */
325   if (mpfr_get_exp (t) >= precz + 14)
326     mpfr_mul_2ui (t, t, 1, MPFR_RNDU);
327   else
328     mpfr_set_ui_2exp (t, 1, precz + 14, MPFR_RNDU);
329   /* now t = max(1/eps,2*sd) */
330   mpfr_add_ui (u, u, 1, MPFR_RNDU); /* u = 1+eps, rounded up */
331   mpfr_mul (t, t, u, MPFR_RNDU); /* t = max(1/eps,2*sd)*(1+eps) */
332   mpfr_add_ui (m1, t, 1, MPFR_RNDU);
333   if (mpfr_get_exp (m1) <= 3)
334     mpfr_set_ui (t, 8, MPFR_RNDU);
335   else
336     mpfr_set (t, m1, MPFR_RNDU);
337   /* now t = max(8,m1) */
338   mpfr_div_2ui (t, t, precz + 14, MPFR_RNDU); /* eps*max(8,m1) */
339   mpfr_add_ui (t, t, 1, MPFR_RNDU); /* 1+eps*max(8,m1) */
340   mpfr_mul (t, t, u, MPFR_RNDU); /* t = c */
341   mpfr_add_ui (u, m1, 13, MPFR_RNDU); /* 13+m1 */
342   mpfr_mul (u, u, t, MPFR_RNDU); /* c*(13+m1) */
343   mpfr_sqr (t, t, MPFR_RNDU); /* c^2 */
344   mpfr_mul (u, u, t, MPFR_RNDU); /* c^3*(13+m1) */
345   add = mpfr_get_exp (u);
346   mpfr_clears (t, u, m1, (mpfr_ptr) 0);
347   return add;
348 }
349 
350 /* return in z a lower bound (for rnd = RNDD) or upper bound (for rnd = RNDU)
351    of |zeta(s)|/2, using:
352    log(|zeta(s)|/2) = (s-1)*log(2*Pi) + lngamma(1-s)
353    + log(|sin(Pi*s/2)| * zeta(1-s)).
354    Assumes s < 1/2 and s1 = 1-s exactly, thus s1 > 1/2.
355    y and p are temporary variables.
356    At input, p is Pi rounded down.
357    The comments in the code are for rnd = RNDD. */
358 static void
mpfr_reflection_overflow(mpfr_ptr z,mpfr_ptr s1,mpfr_srcptr s,mpfr_ptr y,mpfr_ptr p,mpfr_rnd_t rnd)359 mpfr_reflection_overflow (mpfr_ptr z, mpfr_ptr s1, mpfr_srcptr s, mpfr_ptr y,
360                           mpfr_ptr p, mpfr_rnd_t rnd)
361 {
362   mpz_t sint;
363 
364   MPFR_ASSERTD (rnd == MPFR_RNDD || rnd == MPFR_RNDU);
365 
366   /* Since log is increasing, we want lower bounds on |sin(Pi*s/2)| and
367      zeta(1-s). */
368   mpz_init (sint);
369   mpfr_get_z (sint, s, MPFR_RNDD); /* sint = floor(s) */
370   /* We first compute a lower bound of |sin(Pi*s/2)|, which is a periodic
371      function of period 2. Thus:
372      if 2k < s < 2k+1, then |sin(Pi*s/2)| is increasing;
373      if 2k-1 < s < 2k, then |sin(Pi*s/2)| is decreasing.
374      These cases are distinguished by testing bit 0 of floor(s) as if
375      represented in two's complement (or equivalently, as an unsigned
376      integer mod 2):
377      0: sint = 0 mod 2, thus 2k < s < 2k+1 and |sin(Pi*s/2)| is increasing;
378      1: sint = 1 mod 2, thus 2k-1 < s < 2k and |sin(Pi*s/2)| is decreasing.
379      Let's recall that the comments are for rnd = RNDD. */
380   if (mpz_tstbit (sint, 0) == 0) /* |sin(Pi*s/2)| is increasing: round down
381                                     Pi*s to get a lower bound. */
382     {
383       mpfr_mul (y, p, s, rnd);
384       if (rnd == MPFR_RNDD)
385         mpfr_nextabove (p); /* we will need p rounded above afterwards */
386     }
387   else /* |sin(Pi*s/2)| is decreasing: round up Pi*s to get a lower bound. */
388     {
389       if (rnd == MPFR_RNDD)
390         mpfr_nextabove (p);
391       mpfr_mul (y, p, s, MPFR_INVERT_RND(rnd));
392     }
393   mpfr_div_2ui (y, y, 1, MPFR_RNDN); /* exact, rounding mode doesn't matter */
394   /* The rounding direction of sin depends on its sign. We have:
395      if -4k-2 < s < -4k, then -2k-1 < s/2 < -2k, thus sin(Pi*s/2) < 0;
396      if -4k < s < -4k+2, then -2k < s/2 < -2k+1, thus sin(Pi*s/2) > 0.
397      These cases are distinguished by testing bit 1 of floor(s) as if
398      represented in two's complement (or equivalently, as an unsigned
399      integer mod 4):
400      0: sint = {0,1} mod 4, thus -2k < s/2 < -2k+1 and sin(Pi*s/2) > 0;
401      1: sint = {2,3} mod 4, thus -2k-1 < s/2 < -2k and sin(Pi*s/2) < 0.
402      Let's recall that the comments are for rnd = RNDD. */
403   if (mpz_tstbit (sint, 1) == 0) /* -2k < s/2 < -2k+1; sin(Pi*s/2) > 0 */
404     {
405       /* Round sin down to get a lower bound of |sin(Pi*s/2)|. */
406       mpfr_sin (y, y, rnd);
407     }
408   else /* -2k-1 < s/2 < -2k; sin(Pi*s/2) < 0 */
409     {
410       /* Round sin up to get a lower bound of |sin(Pi*s/2)|. */
411       mpfr_sin (y, y, MPFR_INVERT_RND(rnd));
412       mpfr_abs (y, y, MPFR_RNDN); /* exact, rounding mode doesn't matter */
413     }
414   mpz_clear (sint);
415   /* now y <= |sin(Pi*s/2)| when rnd=RNDD, y >= |sin(Pi*s/2)| when rnd=RNDU */
416   mpfr_zeta_pos (z, s1, rnd); /* zeta(1-s) */
417   mpfr_mul (z, z, y, rnd);
418   /* now z <= |sin(Pi*s/2)|*zeta(1-s) */
419   mpfr_log (z, z, rnd);
420   /* now z <= log(|sin(Pi*s/2)|*zeta(1-s)) */
421   mpfr_lngamma (y, s1, rnd);
422   mpfr_add (z, z, y, rnd);
423   /* z <= lngamma(1-s) + log(|sin(Pi*s/2)|*zeta(1-s)) */
424   /* since s-1 < 0, we want to round log(2*pi) upwards */
425   mpfr_mul_2ui (y, p, 1, MPFR_INVERT_RND(rnd));
426   mpfr_log (y, y, MPFR_INVERT_RND(rnd));
427   mpfr_mul (y, y, s1, MPFR_INVERT_RND(rnd));
428   mpfr_sub (z, z, y, rnd);
429   mpfr_exp (z, z, rnd);
430   if (rnd == MPFR_RNDD)
431     mpfr_nextbelow (p); /* restore original p */
432 }
433 
434 int
mpfr_zeta(mpfr_ptr z,mpfr_srcptr s,mpfr_rnd_t rnd_mode)435 mpfr_zeta (mpfr_ptr z, mpfr_srcptr s, mpfr_rnd_t rnd_mode)
436 {
437   mpfr_t z_pre, s1, y, p;
438   long add;
439   mpfr_prec_t precz, prec1, precs, precs1;
440   int inex;
441   MPFR_GROUP_DECL (group);
442   MPFR_ZIV_DECL (loop);
443   MPFR_SAVE_EXPO_DECL (expo);
444 
445   MPFR_LOG_FUNC (
446     ("s[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (s), mpfr_log_prec, s, rnd_mode),
447     ("z[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (z), mpfr_log_prec, z, inex));
448 
449   /* Zero, Nan or Inf ? */
450   if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (s)))
451     {
452       if (MPFR_IS_NAN (s))
453         {
454           MPFR_SET_NAN (z);
455           MPFR_RET_NAN;
456         }
457       else if (MPFR_IS_INF (s))
458         {
459           if (MPFR_IS_POS (s))
460             return mpfr_set_ui (z, 1, MPFR_RNDN); /* Zeta(+Inf) = 1 */
461           MPFR_SET_NAN (z); /* Zeta(-Inf) = NaN */
462           MPFR_RET_NAN;
463         }
464       else /* s iz zero */
465         {
466           MPFR_ASSERTD (MPFR_IS_ZERO (s));
467           return mpfr_set_si_2exp (z, -1, -1, rnd_mode);
468         }
469     }
470 
471   /* s is neither Nan, nor Inf, nor Zero */
472 
473   /* check tiny s: we have zeta(s) = -1/2 - 1/2 log(2 Pi) s + ... around s=0,
474      and for |s| <= 2^(-4), we have |zeta(s) + 1/2| <= |s|.
475      EXP(s) + 1 < -PREC(z) is a sufficient condition to be able to round
476      correctly, for any PREC(z) >= 1 (see algorithms.tex for details). */
477   if (MPFR_GET_EXP (s) + 1 < - (mpfr_exp_t) MPFR_PREC(z))
478     {
479       int signs = MPFR_SIGN(s);
480 
481       MPFR_SAVE_EXPO_MARK (expo);
482       mpfr_set_si_2exp (z, -1, -1, rnd_mode); /* -1/2 */
483       if (rnd_mode == MPFR_RNDA)
484         rnd_mode = MPFR_RNDD; /* the result is around -1/2, thus negative */
485       if ((rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDZ) && signs < 0)
486         {
487           mpfr_nextabove (z); /* z = -1/2 + epsilon */
488           inex = 1;
489         }
490       else if (rnd_mode == MPFR_RNDD && signs > 0)
491         {
492           mpfr_nextbelow (z); /* z = -1/2 - epsilon */
493           inex = -1;
494         }
495       else
496         {
497           if (rnd_mode == MPFR_RNDU) /* s > 0: z = -1/2 */
498             inex = 1;
499           else if (rnd_mode == MPFR_RNDD)
500             inex = -1;              /* s < 0: z = -1/2 */
501           else /* (MPFR_RNDZ and s > 0) or MPFR_RNDN: z = -1/2 */
502             inex = (signs > 0) ? 1 : -1;
503         }
504       MPFR_SAVE_EXPO_FREE (expo);
505       return mpfr_check_range (z, inex, rnd_mode);
506     }
507 
508   /* Check for case s= -2n */
509   if (MPFR_IS_NEG (s))
510     {
511       mpfr_t tmp;
512       tmp[0] = *s;
513       MPFR_EXP (tmp) = MPFR_GET_EXP (s) - 1;
514       if (mpfr_integer_p (tmp))
515         {
516           MPFR_SET_ZERO (z);
517           MPFR_SET_POS (z);
518           MPFR_RET (0);
519         }
520     }
521 
522   /* Check for case s=1 before changing the exponent range */
523   if (mpfr_cmp (s, __gmpfr_one) == 0)
524     {
525       MPFR_SET_INF (z);
526       MPFR_SET_POS (z);
527       MPFR_SET_DIVBY0 ();
528       MPFR_RET (0);
529     }
530 
531   MPFR_SAVE_EXPO_MARK (expo);
532 
533   /* Compute Zeta */
534   if (MPFR_IS_POS (s) && MPFR_GET_EXP (s) >= 0) /* Case s >= 1/2 */
535     inex = mpfr_zeta_pos (z, s, rnd_mode);
536   else /* use reflection formula
537           zeta(s) = 2^s*Pi^(s-1)*sin(Pi*s/2)*gamma(1-s)*zeta(1-s) */
538     {
539       int overflow = 0;
540 
541       precz = MPFR_PREC (z);
542       precs = MPFR_PREC (s);
543 
544       /* Precision precs1 needed to represent 1 - s, and s + 2,
545          without any truncation */
546       precs1 = precs + 2 + MAX (0, - MPFR_GET_EXP (s));
547       /* Precision prec1 is the precision on elementary computations;
548          it ensures a final precision prec1 - add for zeta(s) */
549       add = compute_add (s, precz);
550       prec1 = precz + add;
551       /* FIXME: To avoid that the working precision (prec1) depends on the
552          input precision, one would need to take into account the error made
553          when s1 is not exactly 1-s when computing zeta(s1) and gamma(s1)
554          below, and also in the case y=Inf (i.e. when gamma(s1) overflows).
555          Make sure that underflows do not occur in intermediate computations.
556          Due to the limited precision, they are probably not possible
557          in practice; add some MPFR_ASSERTN's to be sure that problems
558          do not remain undetected? */
559       prec1 = MAX (prec1, precs1) + 10;
560 
561       MPFR_GROUP_INIT_4 (group, prec1, z_pre, s1, y, p);
562       MPFR_ZIV_INIT (loop, prec1);
563       for (;;)
564         {
565           mpfr_exp_t ey;
566           mpfr_t z_up;
567 
568           mpfr_const_pi (p, MPFR_RNDD); /* p is Pi */
569 
570           mpfr_sub (s1, __gmpfr_one, s, MPFR_RNDN); /* s1 = 1-s */
571           mpfr_gamma (y, s1, MPFR_RNDN);          /* gamma(1-s) */
572           if (MPFR_IS_INF (y)) /* zeta(s) < 0 for -4k-2 < s < -4k,
573                                   zeta(s) > 0 for -4k < s < -4k+2 */
574             {
575               /* FIXME: An overflow in gamma(s1) does not imply that
576                  zeta(s) will overflow. A solution:
577                  1. Compute
578                    log(|zeta(s)|/2) = (s-1)*log(2*pi) + lngamma(1-s)
579                      + log(abs(sin(Pi*s/2)) * zeta(1-s))
580                  (possibly sharing computations with the normal case)
581                  with a rather good accuracy (see (2)).
582                  Memorize the sign of sin(...) for the final sign.
583                  2. Take the exponential, ~= |zeta(s)|/2. If there is an
584                  overflow, then this means an overflow on the final result
585                  (due to the multiplication by 2, which has not been done
586                  yet).
587                  3. Ziv test.
588                  4. Correct the sign from the sign of sin(...).
589                  5. Round then multiply by 2. Here, an overflow in either
590                  operation means a real overflow. */
591               mpfr_reflection_overflow (z_pre, s1, s, y, p, MPFR_RNDD);
592               /* z_pre is a lower bound of |zeta(s)|/2, thus if it overflows,
593                  or has exponent emax, then |zeta(s)| overflows too. */
594               if (MPFR_IS_INF (z_pre) || MPFR_GET_EXP(z_pre) == __gmpfr_emax)
595                 { /* determine the sign of overflow */
596                   mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */
597                   mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */
598                   overflow = (mpfr_cmp_si_2exp (s1, -1, -1) > 0) ? -1 : 1;
599                   break;
600                 }
601               else /* EXP(z_pre) < __gmpfr_emax */
602                 {
603                   int ok = 0;
604                   mpfr_t z_down;
605                   mpfr_init2 (z_up, mpfr_get_prec (z_pre));
606                   mpfr_reflection_overflow (z_up, s1, s, y, p, MPFR_RNDU);
607                   /* if the lower approximation z_pre does not overflow, but
608                      z_up does, we need more precision */
609                   if (MPFR_IS_INF (z_up) || MPFR_GET_EXP(z_up) == __gmpfr_emax)
610                     goto next_loop;
611                   /* check if z_pre and z_up round to the same number */
612                   mpfr_init2 (z_down, precz);
613                   mpfr_set (z_down, z_pre, rnd_mode);
614                   /* Note: it might be that EXP(z_down) = emax here, in that
615                      case we will have overflow below when we multiply by 2 */
616                   mpfr_prec_round (z_up, precz, rnd_mode);
617                   ok = mpfr_cmp (z_down, z_up) == 0;
618                   mpfr_clear (z_up);
619                   mpfr_clear (z_down);
620                   if (ok)
621                     {
622                       /* get correct sign and multiply by 2 */
623                       mpfr_div_2ui (s1, s, 2, MPFR_RNDN); /* s/4, exact */
624                       mpfr_frac (s1, s1, MPFR_RNDN); /* exact, -1 < s1 < 0 */
625                       if (mpfr_cmp_si_2exp (s1, -1, -1) > 0)
626                         mpfr_neg (z_pre, z_pre, rnd_mode);
627                       mpfr_mul_2ui (z_pre, z_pre, 1, rnd_mode);
628                       break;
629                     }
630                   else
631                     goto next_loop;
632                 }
633             }
634           mpfr_zeta_pos (z_pre, s1, MPFR_RNDN);   /* zeta(1-s)  */
635           mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);  /* gamma(1-s)*zeta(1-s) */
636 
637           /* multiply z_pre by 2^s*Pi^(s-1) where p=Pi, s1=1-s */
638           mpfr_mul_2ui (y, p, 1, MPFR_RNDN);      /* 2*Pi */
639           mpfr_neg (s1, s1, MPFR_RNDN);           /* s-1 */
640           mpfr_pow (y, y, s1, MPFR_RNDN);         /* (2*Pi)^(s-1) */
641           mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);
642           mpfr_mul_2ui (z_pre, z_pre, 1, MPFR_RNDN);
643 
644           /* multiply z_pre by sin(Pi*s/2) */
645           mpfr_mul (y, s, p, MPFR_RNDN);
646           mpfr_div_2ui (p, y, 1, MPFR_RNDN);      /* p = s*Pi/2 */
647           /* FIXME: sinpi will be available, we should replace the mpfr_sin
648              call below by mpfr_sinpi(s/2), where s/2 will be exact.
649              Can mpfr_sin underflow? Moreover, the code below should be
650              improved so that the "if" condition becomes unlikely, e.g.
651              by taking a slightly larger working precision. */
652           mpfr_sin (y, p, MPFR_RNDN);             /* y = sin(Pi*s/2) */
653           ey = MPFR_GET_EXP (y);
654           if (ey < 0) /* take account of cancellation in sin(p) */
655             {
656               mpfr_t t;
657 
658               MPFR_ASSERTN (- ey < MPFR_PREC_MAX - prec1);
659               mpfr_init2 (t, prec1 - ey);
660               mpfr_const_pi (t, MPFR_RNDD);
661               mpfr_mul (t, s, t, MPFR_RNDN);
662               mpfr_div_2ui (t, t, 1, MPFR_RNDN);
663               mpfr_sin (y, t, MPFR_RNDN);
664               mpfr_clear (t);
665             }
666           mpfr_mul (z_pre, z_pre, y, MPFR_RNDN);
667 
668           if (MPFR_LIKELY (MPFR_CAN_ROUND (z_pre, prec1 - add, precz,
669                                            rnd_mode)))
670             break;
671 
672         next_loop:
673           MPFR_ZIV_NEXT (loop, prec1);
674           MPFR_GROUP_REPREC_4 (group, prec1, z_pre, s1, y, p);
675         }
676       MPFR_ZIV_FREE (loop);
677       if (overflow != 0)
678         {
679           inex = mpfr_overflow (z, rnd_mode, overflow);
680           MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW);
681         }
682       else
683         inex = mpfr_set (z, z_pre, rnd_mode);
684       MPFR_GROUP_CLEAR (group);
685     }
686 
687   MPFR_SAVE_EXPO_FREE (expo);
688   return mpfr_check_range (z, inex, rnd_mode);
689 }
690