xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tli2.c (revision 62f324d0121177eaf2e0384f92fd9ca2a751c795)
1 /* mpfr_tli2 -- test file for dilogarithm function
2 
3 Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Cacao projects, INRIA.
5 
6 The GNU MPFR Library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or (at your
9 option) any later version.
10 
11 The GNU MPFR Library is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14 License for more details.
15 
16 You should have received a copy of the GNU Lesser General Public License
17 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
18 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
19 51 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 
31 static void
32 special (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 
83 static void
84 normal (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 
150 static void
151 bug20091013 (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 
178 int
179 main (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 
199 int
200 main (void)
201 {
202   printf ("Warning! Test disabled for this MPFR version.\n");
203   return 0;
204 }
205 
206 #endif
207