1/* mpfr_tli2 -- test file for dilogarithm function
2
3Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4Contributed by the Arenaire and Cacao projects, INRIA.
5
6The GNU MPFR Library is free software; you can redistribute it and/or modify
7it under the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation; either version 3 of the License, or (at your
9option) any later version.
10
11The GNU MPFR Library is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
18http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
1951 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
20
21#include <stdio.h>
22#include <stdlib.h>
23
24#include "mpfr-test.h"
25
26#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
27
28#define TEST_FUNCTION mpfr_li2
29#include "tgeneric.c"
30
31static void
32special (void)
33{
34  mpfr_t x, y;
35  mpfr_init (x);
36  mpfr_init (y);
37
38  mpfr_set_nan (x);
39  mpfr_li2 (y, x, MPFR_RNDN);
40  if (!mpfr_nan_p (y))
41    {
42      printf ("Error for li2(NaN)\n");
43      exit (1);
44    }
45
46  mpfr_set_inf (x, -1);
47  mpfr_li2 (y, x, MPFR_RNDN);
48  if (!MPFR_IS_INF (y) || MPFR_IS_POS (y))
49    {
50      printf ("Error for li2(-Inf)\n");
51      exit (1);
52    }
53
54  mpfr_set_inf (x, 1);
55  mpfr_li2 (y, x, MPFR_RNDN);
56  if (!MPFR_IS_INF (y) || MPFR_IS_POS (y))
57    {
58      printf ("Error for li2(+Inf)\n");
59      exit (1);
60    }
61
62  mpfr_set_ui (x, 0, MPFR_RNDN);
63  mpfr_li2 (y, x, MPFR_RNDN);
64  if (!MPFR_IS_ZERO (y) || MPFR_IS_NEG (y))
65    {
66      printf ("Error for li2(+0)\n");
67      exit (1);
68    }
69
70  mpfr_set_ui (x, 0, MPFR_RNDN);
71  mpfr_neg (x, x, MPFR_RNDN);
72  mpfr_li2 (y, x, MPFR_RNDN);
73  if (!MPFR_IS_ZERO (y) || MPFR_IS_POS (y))
74    {
75      printf ("Error for li2(-0)\n");
76      exit (1);
77    }
78
79  mpfr_clear (x);
80  mpfr_clear (y);
81}
82
83static void
84normal (void)
85{
86  int inexact;
87  mpfr_t x, y;
88  mpfr_init (x);
89  mpfr_init (y);
90
91  /* x1 = 2^-3 */
92  mpfr_set_str (x, "1p-3", 2, MPFR_RNDD);
93  mpfr_li2 (x, x, MPFR_RNDN);
94  if (mpfr_cmp_str (x, "0x1087a7a9e42141p-55", 16, MPFR_RNDN) != 0)
95    {
96      printf ("Error for li2(x1)\n");
97      exit (1);
98    }
99
100  /* check MPFR_FAST_COMPUTE_IF_SMALL_INPUT */
101  mpfr_set_prec (x, 2);
102  mpfr_set_prec (y, 20);
103  mpfr_set_ui_2exp (x, 1, -21, MPFR_RNDN);
104  mpfr_li2 (y, x, MPFR_RNDN);
105  MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
106
107  mpfr_set_si_2exp (x, -1, -21, MPFR_RNDN);
108  mpfr_li2 (y, x, MPFR_RNDN);
109  MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
110
111  /* worst case */
112  /* x2 = 0x7F18EA6537E00E983196CDDC6EFAC57Fp-129
113     Li2(x2) = 2^-2 + 2^-6 + 2^-120 */
114  mpfr_set_prec (x, 128);
115  mpfr_set_str (x, "7F18EA6537E00E983196CDDC6EFAC57Fp-129", 16, MPFR_RNDN);
116
117  /* round to nearest mode and 4 bits of precision,
118     it should be rounded to 2^-2 + 2^-5 and */
119  mpfr_set_prec (y, 4);
120  inexact = mpfr_li2 (y, x, MPFR_RNDN);
121  if (inexact != 1 || mpfr_cmp_str (y, "0.1001p-1", 2, MPFR_RNDN) != 0)
122    {
123      printf ("Error for li2(x2, RNDN)\n");
124      exit (1);
125    }
126
127  /* round toward zero mode and 5 bits of precision,
128     it should be rounded to 2^-2 + 2^-6 */
129  mpfr_set_prec (y, 5);
130  inexact = mpfr_li2 (y, x, MPFR_RNDZ);
131  if (inexact != -1 || mpfr_cmp_str (y, "0.10001p-1", 2, MPFR_RNDN) != 0)
132    {
133      printf ("Error for li2(x2, RNDZ)\n");
134      exit (1);
135    }
136
137  /* round away from zero mode and 5 bits of precision,
138     it should be rounded to 2^-2 + 2^-5 */
139  inexact = mpfr_li2 (y, x, MPFR_RNDU);
140  if (inexact != 1 || mpfr_cmp_str (y, "0.10010p-1", 2, MPFR_RNDN) != 0)
141    {
142      printf ("Error for li2(x2, RNDU)\n");
143      exit (1);
144    }
145
146  mpfr_clear (x);
147  mpfr_clear (y);
148}
149
150static void
151bug20091013 (void)
152{
153  mpfr_t x, y;
154  int inex;
155
156  mpfr_init2 (x, 17);
157  mpfr_init2 (y, 2);
158  mpfr_set_str_binary (x, "0.10000000000000000E-16");
159  inex = mpfr_li2 (y, x, MPFR_RNDN);
160  if (mpfr_cmp_ui_2exp (y, 1, -17) != 0)
161    {
162      printf ("Error in bug20091013()\n");
163      printf ("expected 2^(-17)\n");
164      printf ("got      ");
165      mpfr_dump (y);
166      exit (1);
167    }
168  if (inex >= 0)
169    {
170      printf ("Error in bug20091013()\n");
171      printf ("expected negative ternary value, got %d\n", inex);
172      exit (1);
173    }
174  mpfr_clear (x);
175  mpfr_clear (y);
176}
177
178int
179main (int argc, char *argv[])
180{
181  tests_start_mpfr ();
182
183  bug20091013 ();
184
185  special ();
186
187  normal ();
188
189  test_generic (2, 100, 2);
190
191  data_check ("data/li2", mpfr_li2, "mpfr_li2");
192
193  tests_end_mpfr ();
194  return 0;
195}
196
197#else
198
199int
200main (void)
201{
202  printf ("Warning! Test disabled for this MPFR version.\n");
203  return 0;
204}
205
206#endif
207