1 /* mpfr_li2 -- Dilogarithm.
2
3 Copyright 2007-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 #define MPFR_NEED_LONGLONG_H
24 #include "mpfr-impl.h"
25
26 /* Compute the alternating series
27 s = S(z) = \sum_{k=0}^infty B_{2k} (z))^{2k+1} / (2k+1)!
28 with 0 < z <= log(2) to the precision of s rounded in the direction
29 rnd_mode.
30 Return the maximum index of the truncature which is useful
31 for determinating the relative error.
32 */
33 static int
li2_series(mpfr_ptr sum,mpfr_srcptr z,mpfr_rnd_t rnd_mode)34 li2_series (mpfr_ptr sum, mpfr_srcptr z, mpfr_rnd_t rnd_mode)
35 {
36 int i;
37 mpfr_t s, u, v, w;
38 mpfr_prec_t sump, p;
39 mpfr_exp_t se, err;
40 MPFR_ZIV_DECL (loop);
41
42 /* The series converges for |z| < 2 pi, but in mpfr_li2 the argument is
43 reduced so that 0 < z <= log(2). Here is an additional check that z
44 is (nearly) correct. */
45 MPFR_ASSERTD (MPFR_IS_STRICTPOS (z));
46 MPFR_ASSERTD (mpfr_cmp_ui_2exp (z, 89, -7) <= 0); /* z <= 0.6953125 */
47
48 sump = MPFR_PREC (sum); /* target precision */
49 p = sump + MPFR_INT_CEIL_LOG2 (sump) + 4; /* the working precision */
50 mpfr_init2 (s, p);
51 mpfr_init2 (u, p);
52 mpfr_init2 (v, p);
53 mpfr_init2 (w, p);
54
55 MPFR_ZIV_INIT (loop, p);
56 for (;;)
57 {
58 mpfr_sqr (u, z, MPFR_RNDU);
59 mpfr_set (v, z, MPFR_RNDU);
60 mpfr_set (s, z, MPFR_RNDU);
61 se = MPFR_GET_EXP (s);
62 err = 0;
63
64 for (i = 1;; i++)
65 {
66 mpfr_mul (v, u, v, MPFR_RNDU);
67 mpfr_div_ui (v, v, 2 * i, MPFR_RNDU);
68 mpfr_div_ui (v, v, 2 * i, MPFR_RNDU);
69 mpfr_div_ui (v, v, 2 * i + 1, MPFR_RNDU);
70 mpfr_div_ui (v, v, 2 * i + 1, MPFR_RNDU);
71 /* here, v_2i = v_{2i-2} / (2i * (2i+1))^2 */
72
73 mpfr_mul_z (w, v, mpfr_bernoulli_cache(i), MPFR_RNDN);
74 /* here, w_2i = v_2i * B_2i * (2i+1)! with
75 error(w_2i) < 2^(5 * i + 8) ulp(w_2i) (see algorithms.tex) */
76
77 mpfr_add (s, s, w, MPFR_RNDN);
78
79 err = MAX (err + se, 5 * i + 8 + MPFR_GET_EXP (w))
80 - MPFR_GET_EXP (s);
81 err = 2 + MAX (-1, err);
82 se = MPFR_GET_EXP (s);
83 if (MPFR_GET_EXP (w) <= se - (mpfr_exp_t) p)
84 break;
85 }
86
87 /* the previous value of err is the rounding error,
88 the truncation error is less than EXP(z) - 6 * i - 5
89 (see algorithms.tex) */
90 err = MAX (err, MPFR_GET_EXP (z) - 6 * i - 5) + 1;
91 if (MPFR_CAN_ROUND (s, (mpfr_exp_t) p - err, sump, rnd_mode))
92 break;
93
94 MPFR_ZIV_NEXT (loop, p);
95 mpfr_set_prec (s, p);
96 mpfr_set_prec (u, p);
97 mpfr_set_prec (v, p);
98 mpfr_set_prec (w, p);
99 }
100 MPFR_ZIV_FREE (loop);
101 mpfr_set (sum, s, rnd_mode);
102
103 mpfr_clears (s, u, v, w, (mpfr_ptr) 0);
104
105 /* Let K be the returned value.
106 1. As we compute an alternating series, the truncation error has the same
107 sign as the next term w_{K+2} which is positive iff K%4 == 0.
108 2. Assume that error(z) <= (1+t) z', where z' is the actual value, then
109 error(s) <= 2 * (K+1) * t (see algorithms.tex).
110 */
111 return 2 * i;
112 }
113
114 /* try asymptotic expansion when x is large and positive:
115 Li2(x) = -log(x)^2/2 + Pi^2/3 - 1/x + O(1/x^2).
116 More precisely for x >= 2 we have for g(x) = -log(x)^2/2 + Pi^2/3:
117 -2 <= x * (Li2(x) - g(x)) <= -1
118 thus |Li2(x) - g(x)| <= 2/x.
119 Assumes x >= 38, which ensures log(x)^2/2 >= 2*Pi^2/3, and g(x) <= -3.3.
120 Return 0 if asymptotic expansion failed (unable to round), otherwise
121 returns 1 for RNDF, and correct ternary value otherwise.
122 */
123 static int
mpfr_li2_asympt_pos(mpfr_ptr y,mpfr_srcptr x,mpfr_rnd_t rnd_mode)124 mpfr_li2_asympt_pos (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
125 {
126 mpfr_t g, h;
127 mpfr_prec_t w = MPFR_PREC (y) + 20;
128 int inex = 0;
129
130 MPFR_ASSERTN (mpfr_cmp_ui (x, 38) >= 0);
131
132 mpfr_init2 (g, w);
133 mpfr_init2 (h, w);
134 mpfr_log (g, x, MPFR_RNDN); /* rel. error <= |(1 + theta) - 1| */
135 mpfr_sqr (g, g, MPFR_RNDN); /* rel. error <= |(1 + theta)^3 - 1| <= 2^(2-w) */
136 mpfr_div_2ui (g, g, 1, MPFR_RNDN); /* rel. error <= 2^(2-w) */
137 mpfr_const_pi (h, MPFR_RNDN); /* error <= 2^(1-w) */
138 mpfr_sqr (h, h, MPFR_RNDN); /* rel. error <= 2^(2-w) */
139 mpfr_div_ui (h, h, 3, MPFR_RNDN); /* rel. error <= |(1 + theta)^4 - 1|
140 <= 5 * 2^(-w) */
141 /* since x is chosen such that log(x)^2/2 >= 2 * (Pi^2/3), we should have
142 g >= 2*h, thus |g-h| >= |h|, and the relative error on g is at most
143 multiplied by 2 in the difference, and that by h is unchanged. */
144 MPFR_ASSERTN (MPFR_EXP (g) > MPFR_EXP (h));
145 mpfr_sub (g, h, g, MPFR_RNDN); /* err <= ulp(g)/2 + g*2^(3-w) + g*5*2^(-w)
146 <= ulp(g) * (1/2 + 8 + 5) < 14 ulp(g).
147
148 If in addition 2/x <= 2 ulp(g), i.e.,
149 1/x <= ulp(g), then the total error is
150 bounded by 16 ulp(g). */
151 if ((MPFR_EXP (x) >= (mpfr_exp_t) w - MPFR_EXP (g)) &&
152 MPFR_CAN_ROUND (g, w - 4, MPFR_PREC (y), rnd_mode))
153 {
154 inex = mpfr_set (y, g, rnd_mode);
155 if (rnd_mode == MPFR_RNDF)
156 inex = 1;
157 }
158
159 mpfr_clear (g);
160 mpfr_clear (h);
161
162 return inex;
163 }
164
165 /* try asymptotic expansion when x is large and negative:
166 Li2(x) = -log(-x)^2/2 - Pi^2/6 - 1/x + O(1/x^2).
167 More precisely for x <= -2 we have for g(x) = -log(-x)^2/2 - Pi^2/6:
168 |Li2(x) - g(x)| <= 1/|x|.
169 Assumes x <= -7, which ensures |log(-x)^2/2| >= Pi^2/6, and g(x) <= -3.5.
170 Return 0 if asymptotic expansion failed (unable to round), otherwise
171 returns 1 for RNDF, and correct ternary value otherwise.
172 */
173 static int
mpfr_li2_asympt_neg(mpfr_ptr y,mpfr_srcptr x,mpfr_rnd_t rnd_mode)174 mpfr_li2_asympt_neg (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
175 {
176 mpfr_t g, h;
177 mpfr_prec_t w = MPFR_PREC (y) + 20;
178 int inex = 0;
179
180 MPFR_ASSERTN (mpfr_cmp_si (x, -7) <= 0);
181
182 mpfr_init2 (g, w);
183 mpfr_init2 (h, w);
184 mpfr_neg (g, x, MPFR_RNDN);
185 mpfr_log (g, g, MPFR_RNDN); /* rel. error <= |(1 + theta) - 1| */
186 mpfr_sqr (g, g, MPFR_RNDN); /* rel. error <= |(1 + theta)^3 - 1| <= 2^(2-w) */
187 mpfr_div_2ui (g, g, 1, MPFR_RNDN); /* rel. error <= 2^(2-w) */
188 mpfr_const_pi (h, MPFR_RNDN); /* error <= 2^(1-w) */
189 mpfr_sqr (h, h, MPFR_RNDN); /* rel. error <= 2^(2-w) */
190 mpfr_div_ui (h, h, 6, MPFR_RNDN); /* rel. error <= |(1 + theta)^4 - 1|
191 <= 5 * 2^(-w) */
192 MPFR_ASSERTN (MPFR_EXP (g) >= MPFR_EXP (h));
193 mpfr_add (g, g, h, MPFR_RNDN); /* err <= ulp(g)/2 + g*2^(2-w) + g*5*2^(-w)
194 <= ulp(g) * (1/2 + 4 + 5) < 10 ulp(g).
195
196 If in addition |1/x| <= 4 ulp(g), then the
197 total error is bounded by 16 ulp(g). */
198 if ((MPFR_EXP (x) >= (mpfr_exp_t) (w - 2) - MPFR_EXP (g)) &&
199 MPFR_CAN_ROUND (g, w - 4, MPFR_PREC (y), rnd_mode))
200 {
201 inex = mpfr_neg (y, g, rnd_mode);
202 if (rnd_mode == MPFR_RNDF)
203 inex = 1;
204 }
205
206 mpfr_clear (g);
207 mpfr_clear (h);
208
209 return inex;
210 }
211
212 /* Compute the real part of the dilogarithm defined by
213 Li2(x) = -\Int_{t=0}^x log(1-t)/t dt */
214 int
mpfr_li2(mpfr_ptr y,mpfr_srcptr x,mpfr_rnd_t rnd_mode)215 mpfr_li2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
216 {
217 int inexact;
218 mpfr_exp_t err;
219 mpfr_prec_t yp, m;
220 MPFR_ZIV_DECL (loop);
221 MPFR_SAVE_EXPO_DECL (expo);
222
223 MPFR_LOG_FUNC
224 (("x[%Pd]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, rnd_mode),
225 ("y[%Pd]=%.*Rg inexact=%d",
226 mpfr_get_prec (y), mpfr_log_prec, y, inexact));
227
228 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
229 {
230 if (MPFR_IS_NAN (x))
231 {
232 MPFR_SET_NAN (y);
233 MPFR_RET_NAN;
234 }
235 else if (MPFR_IS_INF (x))
236 {
237 MPFR_SET_NEG (y);
238 MPFR_SET_INF (y);
239 MPFR_RET (0);
240 }
241 else /* x is zero */
242 {
243 MPFR_ASSERTD (MPFR_IS_ZERO (x));
244 MPFR_SET_SAME_SIGN (y, x);
245 MPFR_SET_ZERO (y);
246 MPFR_RET (0);
247 }
248 }
249
250 /* Li2(x) = x + x^2/4 + x^3/9 + ..., more precisely for 0 < x <= 1/2
251 we have |Li2(x) - x| < x^2/2 <= 2^(2EXP(x)-1) and for -1/2 <= x < 0
252 we have |Li2(x) - x| < x^2/4 <= 2^(2EXP(x)-2) */
253 if (MPFR_IS_POS (x))
254 MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -MPFR_GET_EXP (x), 1, 1, rnd_mode,
255 {});
256 else
257 MPFR_FAST_COMPUTE_IF_SMALL_INPUT (y, x, -MPFR_GET_EXP (x), 2, 0, rnd_mode,
258 {});
259
260 MPFR_SAVE_EXPO_MARK (expo);
261 yp = MPFR_PREC (y);
262 m = yp + MPFR_INT_CEIL_LOG2 (yp) + 13;
263
264 if (MPFR_LIKELY ((mpfr_cmp_ui (x, 0) > 0) && (mpfr_cmp_ui_2exp (x, 1, -1) <= 0)))
265 /* 0 < x <= 1/2: Li2(x) = S(-log(1-x))-log^2(1-x)/4 */
266 {
267 mpfr_t s, u;
268 mpfr_exp_t expo_l;
269 int k;
270
271 mpfr_init2 (u, m);
272 mpfr_init2 (s, m);
273
274 MPFR_ZIV_INIT (loop, m);
275 for (;;)
276 {
277 mpfr_ui_sub (u, 1, x, MPFR_RNDN);
278 mpfr_log (u, u, MPFR_RNDU);
279 if (MPFR_IS_ZERO(u))
280 goto next_m;
281 mpfr_neg (u, u, MPFR_RNDN); /* u = -log(1-x) */
282 expo_l = MPFR_GET_EXP (u);
283 k = li2_series (s, u, MPFR_RNDU);
284 err = 1 + MPFR_INT_CEIL_LOG2 (k + 1);
285
286 mpfr_sqr (u, u, MPFR_RNDU);
287 mpfr_div_2ui (u, u, 2, MPFR_RNDU); /* u = log^2(1-x) / 4 */
288 mpfr_sub (s, s, u, MPFR_RNDN);
289
290 /* error(s) <= (0.5 + 2^(d-EXP(s))
291 + 2^(3 + MAX(1, - expo_l) - EXP(s))) ulp(s) */
292 err = MAX (err, MAX (1, - expo_l) - 1) - MPFR_GET_EXP (s);
293 err = 2 + MAX (-1, err);
294 if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
295 break;
296
297 next_m:
298 MPFR_ZIV_NEXT (loop, m);
299 mpfr_set_prec (u, m);
300 mpfr_set_prec (s, m);
301 }
302 MPFR_ZIV_FREE (loop);
303 inexact = mpfr_set (y, s, rnd_mode);
304
305 mpfr_clear (u);
306 mpfr_clear (s);
307 MPFR_SAVE_EXPO_FREE (expo);
308 return mpfr_check_range (y, inexact, rnd_mode);
309 }
310 else if (!mpfr_cmp_ui (x, 1))
311 /* Li2(1)= pi^2 / 6 */
312 {
313 mpfr_t u;
314 mpfr_init2 (u, m);
315
316 MPFR_ZIV_INIT (loop, m);
317 for (;;)
318 {
319 mpfr_const_pi (u, MPFR_RNDU);
320 mpfr_sqr (u, u, MPFR_RNDN);
321 mpfr_div_ui (u, u, 6, MPFR_RNDN);
322
323 err = m - 4; /* error(u) <= 19/2 ulp(u) */
324 if (MPFR_CAN_ROUND (u, err, yp, rnd_mode))
325 break;
326
327 MPFR_ZIV_NEXT (loop, m);
328 mpfr_set_prec (u, m);
329 }
330 MPFR_ZIV_FREE (loop);
331 inexact = mpfr_set (y, u, rnd_mode);
332
333 mpfr_clear (u);
334 MPFR_SAVE_EXPO_FREE (expo);
335 return mpfr_check_range (y, inexact, rnd_mode);
336 }
337 else if (mpfr_cmp_ui (x, 2) >= 0)
338 /* x >= 2: Li2(x) = -S(-log(1-1/x))-log^2(x)/2+log^2(1-1/x)/4+pi^2/3 */
339 {
340 int k;
341 mpfr_exp_t expo_l;
342 mpfr_t s, u, xx;
343
344 if (mpfr_cmp_ui (x, 38) >= 0)
345 {
346 inexact = mpfr_li2_asympt_pos (y, x, rnd_mode);
347 if (inexact != 0)
348 goto end_of_case_gt2;
349 }
350
351 mpfr_init2 (u, m);
352 mpfr_init2 (s, m);
353 mpfr_init2 (xx, m);
354
355 MPFR_ZIV_INIT (loop, m);
356 for (;;)
357 {
358 mpfr_ui_div (xx, 1, x, MPFR_RNDN);
359 mpfr_neg (xx, xx, MPFR_RNDN);
360 mpfr_log1p (u, xx, MPFR_RNDD);
361 mpfr_neg (u, u, MPFR_RNDU); /* u = -log(1-1/x) */
362 expo_l = MPFR_GET_EXP (u);
363 k = li2_series (s, u, MPFR_RNDN);
364 mpfr_neg (s, s, MPFR_RNDN);
365 err = MPFR_INT_CEIL_LOG2 (k + 1) + 1; /* error(s) <= 2^err ulp(s) */
366
367 mpfr_sqr (u, u, MPFR_RNDN);
368 mpfr_div_2ui (u, u, 2, MPFR_RNDN); /* u= log^2(1-1/x)/4 */
369 mpfr_add (s, s, u, MPFR_RNDN);
370 err =
371 MAX (err,
372 3 + MAX (1, -expo_l) + MPFR_GET_EXP (u)) - MPFR_GET_EXP (s);
373 err = 2 + MAX (-1, err); /* error(s) <= 2^err ulp(s) */
374 err += MPFR_GET_EXP (s);
375
376 mpfr_log (u, x, MPFR_RNDU);
377 mpfr_sqr (u, u, MPFR_RNDN);
378 mpfr_div_2ui (u, u, 1, MPFR_RNDN); /* u = log^2(x)/2 */
379 mpfr_sub (s, s, u, MPFR_RNDN);
380 err = MAX (err, 3 + MPFR_GET_EXP (u)) - MPFR_GET_EXP (s);
381 err = 2 + MAX (-1, err); /* error(s) <= 2^err ulp(s) */
382 err += MPFR_GET_EXP (s);
383
384 mpfr_const_pi (u, MPFR_RNDU);
385 mpfr_sqr (u, u, MPFR_RNDN);
386 mpfr_div_ui (u, u, 3, MPFR_RNDN); /* u = pi^2/3 */
387 mpfr_add (s, s, u, MPFR_RNDN);
388 err = MAX (err, 2) - MPFR_GET_EXP (s);
389 err = 2 + MAX (-1, err); /* error(s) <= 2^err ulp(s) */
390 if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
391 break;
392
393 MPFR_ZIV_NEXT (loop, m);
394 mpfr_set_prec (u, m);
395 mpfr_set_prec (s, m);
396 mpfr_set_prec (xx, m);
397 }
398 MPFR_ZIV_FREE (loop);
399 inexact = mpfr_set (y, s, rnd_mode);
400 mpfr_clears (s, u, xx, (mpfr_ptr) 0);
401
402 end_of_case_gt2:
403 MPFR_SAVE_EXPO_FREE (expo);
404 return mpfr_check_range (y, inexact, rnd_mode);
405 }
406 else if (mpfr_cmp_ui (x, 1) > 0)
407 /* 2 > x > 1: Li2(x) = S(log(x))+log^2(x)/4-log(x)log(x-1)+pi^2/6 */
408 {
409 int k;
410 mpfr_exp_t e1, e2;
411 mpfr_t s, u, v, xx;
412 mpfr_init2 (s, m);
413 mpfr_init2 (u, m);
414 mpfr_init2 (v, m);
415 mpfr_init2 (xx, m);
416
417 MPFR_ZIV_INIT (loop, m);
418 for (;;)
419 {
420 mpfr_log (v, x, MPFR_RNDU);
421 k = li2_series (s, v, MPFR_RNDN);
422 e1 = MPFR_GET_EXP (s);
423
424 mpfr_sqr (u, v, MPFR_RNDN);
425 mpfr_div_2ui (u, u, 2, MPFR_RNDN); /* u = log^2(x)/4 */
426 mpfr_add (s, s, u, MPFR_RNDN);
427
428 mpfr_sub_ui (xx, x, 1, MPFR_RNDN);
429 mpfr_log (u, xx, MPFR_RNDU);
430 e2 = MPFR_GET_EXP (u);
431 mpfr_mul (u, v, u, MPFR_RNDN); /* u = log(x) * log(x-1) */
432 mpfr_sub (s, s, u, MPFR_RNDN);
433
434 mpfr_const_pi (u, MPFR_RNDU);
435 mpfr_sqr (u, u, MPFR_RNDN);
436 mpfr_div_ui (u, u, 6, MPFR_RNDN); /* u = pi^2/6 */
437 mpfr_add (s, s, u, MPFR_RNDN);
438 /* error(s) <= (31 + (k+1) * 2^(1-e1) + 2^(1-e2)) ulp(s)
439 see algorithms.tex */
440 err = MAX (MPFR_INT_CEIL_LOG2 (k + 1) + 1 - e1, 1 - e2);
441 err = 2 + MAX (5, err);
442 if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
443 break;
444
445 MPFR_ZIV_NEXT (loop, m);
446 mpfr_set_prec (s, m);
447 mpfr_set_prec (u, m);
448 mpfr_set_prec (v, m);
449 mpfr_set_prec (xx, m);
450 }
451 MPFR_ZIV_FREE (loop);
452 inexact = mpfr_set (y, s, rnd_mode);
453
454 mpfr_clears (s, u, v, xx, (mpfr_ptr) 0);
455 MPFR_SAVE_EXPO_FREE (expo);
456 return mpfr_check_range (y, inexact, rnd_mode);
457 }
458 else if (mpfr_cmp_ui_2exp (x, 1, -1) > 0) /* 1/2 < x < 1 */
459 /* 1 > x > 1/2: Li2(x) = -S(-log(x))+log^2(x)/4-log(x)log(1-x)+pi^2/6 */
460 {
461 int k;
462 mpfr_t s, u, v, xx;
463 mpfr_init2 (s, m);
464 mpfr_init2 (u, m);
465 mpfr_init2 (v, m);
466 mpfr_init2 (xx, m);
467
468
469 MPFR_ZIV_INIT (loop, m);
470 for (;;)
471 {
472 mpfr_log (u, x, MPFR_RNDD);
473 mpfr_neg (u, u, MPFR_RNDN);
474 k = li2_series (s, u, MPFR_RNDN);
475 mpfr_neg (s, s, MPFR_RNDN);
476 err = 1 + MPFR_INT_CEIL_LOG2 (k + 1) - MPFR_GET_EXP (s);
477
478 mpfr_ui_sub (xx, 1, x, MPFR_RNDN);
479 mpfr_log (v, xx, MPFR_RNDU);
480 mpfr_mul (v, v, u, MPFR_RNDN); /* v = - log(x) * log(1-x) */
481 mpfr_add (s, s, v, MPFR_RNDN);
482 err = MAX (err, 1 - MPFR_GET_EXP (v));
483 err = 2 + MAX (3, err) - MPFR_GET_EXP (s);
484
485 mpfr_sqr (u, u, MPFR_RNDN);
486 mpfr_div_2ui (u, u, 2, MPFR_RNDN); /* u = log^2(x)/4 */
487 mpfr_add (s, s, u, MPFR_RNDN);
488 err = MAX (err, 2 + MPFR_GET_EXP (u)) - MPFR_GET_EXP (s);
489 err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
490
491 mpfr_const_pi (u, MPFR_RNDU);
492 mpfr_sqr (u, u, MPFR_RNDN);
493 mpfr_div_ui (u, u, 6, MPFR_RNDN); /* u = pi^2/6 */
494 mpfr_add (s, s, u, MPFR_RNDN);
495 err = MAX (err, 3) - MPFR_GET_EXP (s);
496 err = 2 + MAX (-1, err);
497
498 if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
499 break;
500
501 MPFR_ZIV_NEXT (loop, m);
502 mpfr_set_prec (s, m);
503 mpfr_set_prec (u, m);
504 mpfr_set_prec (v, m);
505 mpfr_set_prec (xx, m);
506 }
507 MPFR_ZIV_FREE (loop);
508 inexact = mpfr_set (y, s, rnd_mode);
509
510 mpfr_clears (s, u, v, xx, (mpfr_ptr) 0);
511 MPFR_SAVE_EXPO_FREE (expo);
512 return mpfr_check_range (y, inexact, rnd_mode);
513 }
514 else if (mpfr_cmp_si (x, -1) >= 0)
515 /* 0 > x >= -1: Li2(x) = -S(log(1-x))-log^2(1-x)/4 */
516 {
517 int k;
518 mpfr_exp_t expo_l;
519 mpfr_t s, u, xx;
520 mpfr_init2 (s, m);
521 mpfr_init2 (u, m);
522 mpfr_init2 (xx, m);
523
524 MPFR_ZIV_INIT (loop, m);
525 for (;;)
526 {
527 mpfr_neg (xx, x, MPFR_RNDN);
528 mpfr_log1p (u, xx, MPFR_RNDN);
529 k = li2_series (s, u, MPFR_RNDN);
530 mpfr_neg (s, s, MPFR_RNDN);
531 expo_l = MPFR_GET_EXP (u);
532 err = 1 + MPFR_INT_CEIL_LOG2 (k + 1) - MPFR_GET_EXP (s);
533
534 mpfr_sqr (u, u, MPFR_RNDN);
535 mpfr_div_2ui (u, u, 2, MPFR_RNDN); /* u = log^2(1-x)/4 */
536 mpfr_sub (s, s, u, MPFR_RNDN);
537 err = MAX (err, - expo_l);
538 err = 2 + MAX (err, 3);
539 if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
540 break;
541
542 MPFR_ZIV_NEXT (loop, m);
543 mpfr_set_prec (s, m);
544 mpfr_set_prec (u, m);
545 mpfr_set_prec (xx, m);
546 }
547 MPFR_ZIV_FREE (loop);
548 inexact = mpfr_set (y, s, rnd_mode);
549
550 mpfr_clears (s, u, xx, (mpfr_ptr) 0);
551 MPFR_SAVE_EXPO_FREE (expo);
552 return mpfr_check_range (y, inexact, rnd_mode);
553 }
554 else
555 /* x < -1: Li2(x)
556 = S(log(1-1/x))-log^2(-x)/4-log(1-x)log(-x)/2+log^2(1-x)/4-pi^2/6 */
557 {
558 int k;
559 mpfr_t s, u, v, w, xx;
560
561 if (mpfr_cmp_si (x, -7) <= 0)
562 {
563 inexact = mpfr_li2_asympt_neg (y, x, rnd_mode);
564 if (inexact != 0)
565 goto end_of_case_ltm1;
566 }
567
568 mpfr_init2 (s, m);
569 mpfr_init2 (u, m);
570 mpfr_init2 (v, m);
571 mpfr_init2 (w, m);
572 mpfr_init2 (xx, m);
573
574 MPFR_ZIV_INIT (loop, m);
575 for (;;)
576 {
577 mpfr_ui_div (xx, 1, x, MPFR_RNDN);
578 mpfr_neg (xx, xx, MPFR_RNDN);
579 mpfr_log1p (u, xx, MPFR_RNDN);
580 k = li2_series (s, u, MPFR_RNDN);
581
582 mpfr_ui_sub (xx, 1, x, MPFR_RNDN);
583 mpfr_log (u, xx, MPFR_RNDU);
584 mpfr_neg (xx, x, MPFR_RNDN);
585 mpfr_log (v, xx, MPFR_RNDU);
586 mpfr_mul (w, v, u, MPFR_RNDN);
587 mpfr_div_2ui (w, w, 1, MPFR_RNDN); /* w = log(-x) * log(1-x) / 2 */
588 mpfr_sub (s, s, w, MPFR_RNDN);
589 err = 1 + MAX (3, MPFR_INT_CEIL_LOG2 (k+1) + 1 - MPFR_GET_EXP (s))
590 + MPFR_GET_EXP (s);
591
592 mpfr_sqr (w, v, MPFR_RNDN);
593 mpfr_div_2ui (w, w, 2, MPFR_RNDN); /* w = log^2(-x) / 4 */
594 mpfr_sub (s, s, w, MPFR_RNDN);
595 err = MAX (err, 3 + MPFR_GET_EXP(w)) - MPFR_GET_EXP (s);
596 err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
597
598 mpfr_sqr (w, u, MPFR_RNDN);
599 mpfr_div_2ui (w, w, 2, MPFR_RNDN); /* w = log^2(1-x) / 4 */
600 mpfr_add (s, s, w, MPFR_RNDN);
601 err = MAX (err, 3 + MPFR_GET_EXP (w)) - MPFR_GET_EXP (s);
602 err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
603
604 mpfr_const_pi (w, MPFR_RNDU);
605 mpfr_sqr (w, w, MPFR_RNDN);
606 mpfr_div_ui (w, w, 6, MPFR_RNDN); /* w = pi^2 / 6 */
607 mpfr_sub (s, s, w, MPFR_RNDN);
608 err = MAX (err, 3) - MPFR_GET_EXP (s);
609 err = 2 + MAX (-1, err) + MPFR_GET_EXP (s);
610
611 if (MPFR_CAN_ROUND (s, (mpfr_exp_t) m - err, yp, rnd_mode))
612 break;
613
614 MPFR_ZIV_NEXT (loop, m);
615 mpfr_set_prec (s, m);
616 mpfr_set_prec (u, m);
617 mpfr_set_prec (v, m);
618 mpfr_set_prec (w, m);
619 mpfr_set_prec (xx, m);
620 }
621 MPFR_ZIV_FREE (loop);
622 inexact = mpfr_set (y, s, rnd_mode);
623 mpfr_clears (s, u, v, w, xx, (mpfr_ptr) 0);
624
625 end_of_case_ltm1:
626 MPFR_SAVE_EXPO_FREE (expo);
627 return mpfr_check_range (y, inexact, rnd_mode);
628 }
629
630 MPFR_RET_NEVER_GO_HERE ();
631 }
632