xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tlog.c (revision 154bfe8e089c1a0a4e9ed8414f08d3da90949162)
1 /* Test file for mpfr_log.
2 
3 Copyright 1999, 2001-2018 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 http://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 "mpfr-test.h"
24 
25 #ifdef CHECK_EXTERNAL
26 static int
27 test_log (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
28 {
29   int res;
30   int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53;
31   if (ok)
32     {
33       mpfr_print_raw (b);
34     }
35   res = mpfr_log (a, b, rnd_mode);
36   if (ok)
37     {
38       printf (" ");
39       mpfr_print_raw (a);
40       printf ("\n");
41     }
42   return res;
43 }
44 #else
45 #define test_log mpfr_log
46 #endif
47 
48 static void
49 check2 (const char *as, mpfr_rnd_t rnd_mode, const char *res1s)
50 {
51   mpfr_t ta, tres;
52 
53   mpfr_inits2 (53, ta, tres, (mpfr_ptr) 0);
54   mpfr_set_str1 (ta, as);
55   test_log (tres, ta, rnd_mode);
56 
57   if (mpfr_cmp_str1 (tres, res1s))
58     {
59       printf ("mpfr_log failed for    a=%s, rnd_mode=%s\n",
60               as, mpfr_print_rnd_mode (rnd_mode));
61       printf ("correct result is        %s\n mpfr_log gives          ",
62               res1s);
63       mpfr_out_str(stdout, 10, 0, tres, MPFR_RNDN);
64       printf ("\n");
65       exit (1);
66     }
67   mpfr_clears (ta, tres, (mpfr_ptr) 0);
68 }
69 
70 static void
71 check3 (char *s, unsigned long prec, mpfr_rnd_t rnd)
72 {
73   mpfr_t x, y;
74 
75   mpfr_init2 (x, prec);
76   mpfr_init2 (y, prec);
77   mpfr_set_str (x, s, 10, rnd);
78   test_log (y, x, rnd);
79   mpfr_out_str (stdout, 10, 0, y, rnd);
80   puts ("");
81   mpfr_clear (x);
82   mpfr_clear (y);
83 }
84 
85 /* examples from Jean-Michel Muller and Vincent Lefevre
86    Cf http://www.ens-lyon.fr/~jmmuller/Intro-to-TMD.htm
87 */
88 
89 static void
90 check_worst_cases (void)
91 {
92   check2("1.00089971802309629645", MPFR_RNDD, "8.99313519443722736088e-04");
93   check2("1.00089971802309629645", MPFR_RNDN, "8.99313519443722844508e-04");
94   check2("1.00089971802309629645", MPFR_RNDU, "8.99313519443722844508e-04");
95 
96   check2("1.01979300812244555452", MPFR_RNDD, "1.95996734891603630047e-02");
97   check2("1.01979300812244555452", MPFR_RNDN, "1.95996734891603664741e-02");
98   check2("1.01979300812244555452", MPFR_RNDU, "1.95996734891603664741e-02");
99 
100   check2("1.02900871924604464525", MPFR_RNDD, "2.85959303301472726744e-02");
101   check2("1.02900871924604464525", MPFR_RNDN, "2.85959303301472761438e-02");
102   check2("1.02900871924604464525", MPFR_RNDU, "2.85959303301472761438e-02");
103 
104   check2("1.27832870030418943585", MPFR_RNDD, "2.45553521871417795852e-01");
105   check2("1.27832870030418943585", MPFR_RNDN, "2.45553521871417823608e-01");
106   check2("1.27832870030418943585", MPFR_RNDU, "2.45553521871417823608e-01");
107 
108   check2("1.31706530746788241792", MPFR_RNDD, "2.75406009586277422674e-01");
109   check2("1.31706530746788241792", MPFR_RNDN, "2.75406009586277478185e-01");
110   check2("1.31706530746788241792", MPFR_RNDU, "2.75406009586277478185e-01");
111 
112   check2("1.47116981099449883885", MPFR_RNDD, "3.86057874110010412760e-01");
113   check2("1.47116981099449883885", MPFR_RNDN, "3.86057874110010412760e-01");
114   check2("1.47116981099449883885", MPFR_RNDU, "3.86057874110010468272e-01");
115 
116   check2("1.58405446812987782401", MPFR_RNDD, "4.59987679246663727639e-01");
117   check2("1.58405446812987782401", MPFR_RNDN, "4.59987679246663783150e-01");
118   check2("1.58405446812987782401", MPFR_RNDU, "4.59987679246663783150e-01");
119 
120   check2("1.67192331263391547047", MPFR_RNDD, "5.13974647961076613889e-01");
121   check2("1.67192331263391547047", MPFR_RNDN, "5.13974647961076724911e-01");
122   check2("1.67192331263391547047", MPFR_RNDU, "5.13974647961076724911e-01");
123 
124   check2("1.71101198068990645318", MPFR_RNDD, "5.37084997042120315669e-01");
125   check2("1.71101198068990645318", MPFR_RNDN, "5.37084997042120315669e-01");
126   check2("1.71101198068990645318", MPFR_RNDU, "5.37084997042120426691e-01");
127 
128   check2("1.72634853551388700588", MPFR_RNDD, "5.46008504786553605648e-01");
129   check2("1.72634853551388700588", MPFR_RNDN, "5.46008504786553716670e-01");
130   check2("1.72634853551388700588", MPFR_RNDU, "5.46008504786553716670e-01");
131 
132   check2("2.00028876593004323325", MPFR_RNDD, "6.93291553102749702475e-01");
133   check2("2.00028876593004323325", MPFR_RNDN, "6.93291553102749813497e-01");
134   check2("2.00028876593004323325", MPFR_RNDU, "6.93291553102749813497e-01");
135 
136   check2("6.27593230200363105808", MPFR_RNDD, "1.83672204800630312072");
137   check2("6.27593230200363105808", MPFR_RNDN, "1.83672204800630334276");
138   check2("6.27593230200363105808", MPFR_RNDU, "1.83672204800630334276");
139 
140   check2("7.47216682321367997588", MPFR_RNDD, "2.01118502712453661729");
141   check2("7.47216682321367997588", MPFR_RNDN, "2.01118502712453706138");
142   check2("7.47216682321367997588", MPFR_RNDU, "2.01118502712453706138");
143 
144   check2("9.34589857718275318632", MPFR_RNDD, "2.23493759221664944903");
145   check2("9.34589857718275318632", MPFR_RNDN, "2.23493759221664989312");
146   check2("9.34589857718275318632", MPFR_RNDU, "2.23493759221664989312");
147 
148   check2("10.6856587560831854944", MPFR_RNDD, "2.36890253928838445674");
149   check2("10.6856587560831854944", MPFR_RNDN, "2.36890253928838445674");
150   check2("10.6856587560831854944", MPFR_RNDU, "2.36890253928838490083");
151 
152   check2("12.4646345033981766903", MPFR_RNDD, "2.52289539471636015122");
153   check2("12.4646345033981766903", MPFR_RNDN, "2.52289539471636015122");
154   check2("12.4646345033981766903", MPFR_RNDU, "2.52289539471636059531");
155 
156   check2("17.0953275851761752335", MPFR_RNDD, "2.83880518553861849185");
157   check2("17.0953275851761752335", MPFR_RNDN, "2.83880518553861893594");
158   check2("17.0953275851761752335", MPFR_RNDU, "2.83880518553861893594");
159 
160   check2("19.8509496207496916043", MPFR_RNDD, "2.98825184582516722998");
161   check2("19.8509496207496916043", MPFR_RNDN, "2.98825184582516722998");
162   check2("19.8509496207496916043", MPFR_RNDU, "2.98825184582516767406");
163 
164   check2("23.9512076062771335216", MPFR_RNDD, "3.17601874455977206679");
165   check2("23.9512076062771335216", MPFR_RNDN, "3.17601874455977206679");
166   check2("23.9512076062771335216", MPFR_RNDU, "3.17601874455977251088");
167 
168   check2("428.315247165198229595", MPFR_RNDD, "6.05985948325268264369");
169   check2("428.315247165198229595", MPFR_RNDN, "6.05985948325268353187");
170   check2("428.315247165198229595", MPFR_RNDU, "6.05985948325268353187");
171 }
172 
173 static void
174 special (void)
175 {
176   mpfr_t x, y;
177   int inex;
178   mpfr_exp_t emin, emax;
179 
180   emin = mpfr_get_emin ();
181   emax = mpfr_get_emax ();
182 
183   mpfr_init2 (x, 53);
184   mpfr_init2 (y, 53);
185 
186   /* Check special case: An overflow in const_pi could occurs! */
187   set_emin (-125);
188   set_emax (128);
189   mpfr_set_prec (y, 24*2);
190   mpfr_set_prec (x, 24);
191   mpfr_set_str_binary (x, "0.111110101010101011110101E0");
192   test_log (y, x, MPFR_RNDN);
193   set_emin (emin);
194   set_emax (emax);
195 
196   mpfr_set_prec (y, 53);
197   mpfr_set_prec (x, 53);
198   mpfr_set_ui (x, 3, MPFR_RNDD);
199   test_log (y, x, MPFR_RNDD);
200   if (mpfr_cmp_str1 (y, "1.09861228866810956"))
201     {
202       printf ("Error in mpfr_log(3) for MPFR_RNDD\n");
203       exit (1);
204     }
205 
206   /* check large precision */
207   mpfr_set_prec (x, 3322);
208   mpfr_set_prec (y, 3322);
209   mpfr_set_ui (x, 3, MPFR_RNDN);
210   mpfr_sqrt (x, x, MPFR_RNDN);
211   test_log (y, x, MPFR_RNDN);
212 
213   /* negative argument */
214   mpfr_set_si (x, -1, MPFR_RNDN);
215   test_log (y, x, MPFR_RNDN);
216   MPFR_ASSERTN(mpfr_nan_p (y));
217 
218   /* infinite loop when  */
219   set_emax (128);
220   mpfr_set_prec (x, 251);
221   mpfr_set_prec (y, 251);
222   mpfr_set_str_binary (x, "0.10010111000000000001101E8");
223   /* x = 4947981/32768, log(x) ~ 5.017282... */
224   test_log (y, x, MPFR_RNDN);
225 
226   set_emax (emax);
227 
228   mpfr_set_ui (x, 0, MPFR_RNDN);
229   inex = test_log (y, x, MPFR_RNDN);
230   MPFR_ASSERTN (inex == 0);
231   MPFR_ASSERTN (mpfr_inf_p (y));
232   MPFR_ASSERTN (mpfr_sgn (y) < 0);
233 
234   mpfr_set_ui (x, 0, MPFR_RNDN);
235   mpfr_neg (x, x, MPFR_RNDN);
236   inex = test_log (y, x, MPFR_RNDN);
237   MPFR_ASSERTN (inex == 0);
238   MPFR_ASSERTN (mpfr_inf_p (y));
239   MPFR_ASSERTN (mpfr_sgn (y) < 0);
240 
241   mpfr_clear (x);
242   mpfr_clear (y);
243 }
244 
245 static void
246 x_near_one (void)
247 {
248   mpfr_t x, y;
249   int inex;
250 
251   mpfr_init2 (x, 32);
252   mpfr_init2 (y, 16);
253 
254   mpfr_set_ui (x, 1, MPFR_RNDN);
255   mpfr_nextbelow (x);
256   inex = mpfr_log (y, x, MPFR_RNDD);
257   if (mpfr_cmp_str (y, "-0.1000000000000001E-31", 2, MPFR_RNDN)
258       || inex >= 0)
259     {
260       printf ("Failure in x_near_one, got inex = %d and\ny = ", inex);
261       mpfr_dump (y);
262     }
263 
264   mpfr_clears (x, y, (mpfr_ptr) 0);
265 }
266 
267 #define TEST_FUNCTION test_log
268 #define TEST_RANDOM_POS 8
269 #include "tgeneric.c"
270 
271 int
272 main (int argc, char *argv[])
273 {
274   tests_start_mpfr ();
275 
276   if (argc == 3 || argc == 4)
277     {   /* tlog x prec rnd */
278       check3 (argv[1], strtoul (argv[2], NULL, 10),
279               (argc == 4) ? (mpfr_rnd_t) atoi (argv[3]) : MPFR_RNDN);
280       goto done;
281     }
282 
283   special ();
284   check_worst_cases();
285 
286   check2("1.01979300812244555452", MPFR_RNDN, "1.95996734891603664741e-02");
287   check2("10.0",MPFR_RNDU,"2.30258509299404590110e+00");
288   check2("6.0",MPFR_RNDU,"1.79175946922805517936");
289   check2("1.0",MPFR_RNDZ,"0.0");
290   check2("62.0",MPFR_RNDU,"4.12713438504509166905");
291   check2("0.5",MPFR_RNDZ,"-6.93147180559945286226e-01");
292   check2("3.0",MPFR_RNDZ,"1.09861228866810956006e+00");
293   check2("234375765.0",MPFR_RNDU,"1.92724362186836231104e+01");
294   check2("8.0",MPFR_RNDZ,"2.07944154167983574765e+00");
295   check2("44.0",MPFR_RNDU,"3.78418963391826146392e+00");
296   check2("1.01979300812244555452", MPFR_RNDN, "1.95996734891603664741e-02");
297 
298   /* bugs found by Vincent Lefe`vre */
299   check2("0.99999599881598921769", MPFR_RNDN, "-0.0000040011920155404072924737977900999652547398000024259090423583984375");
300   check2("9.99995576063808955247e-01",MPFR_RNDZ,"-4.42394597667932383816e-06");
301   check2("9.99993687357856209097e-01",MPFR_RNDN,"-6.31266206860017342601e-06");
302   check2("9.99995223520736886691e-01",MPFR_RNDN,"-4.77649067052670982220e-06");
303   check2("9.99993025794720935551e-01",MPFR_RNDN,"-6.97422959894716163837e-06");
304   check2("9.99987549017837484833e-01",MPFR_RNDN,"-1.24510596766369924330e-05");
305   check2("9.99985901426543311032e-01",MPFR_RNDN,"-1.40986728425098585229e-05");
306   check2("9.99986053947420794330e-01",MPFR_RNDN, "-0.000013946149826301084938555592540598837558718514628708362579345703125");
307   check2("9.99971938247442126979e-01",MPFR_RNDN,"-2.80621462962173414790e-05");
308 
309   /* other bugs found by Vincent Lefe`vre */
310   check2("1.18615436389927785905e+77",MPFR_RNDN,"1.77469768607706015473e+02");
311   check2("9.48868723578399476187e+77",MPFR_RNDZ,"1.79549152432275803903e+02");
312   check2("2.31822210096938820854e+89",MPFR_RNDN,"2.05770873832573869322e+02");
313 
314   /* further bugs found by Vincent Lefe`vre */
315   check2("9.99999989485669482647e-01",MPFR_RNDZ,"-1.05143305726283042331e-08");
316   check2("9.99999989237970177136e-01",MPFR_RNDZ,"-1.07620298807745377934e-08");
317   check2("9.99999989239339082125e-01",MPFR_RNDN,"-1.07606609757704445430e-08");
318 
319   check2("7.3890560989306504",MPFR_RNDU,"2.0000000000000004"); /* exp(2.0) */
320   check2("7.3890560989306495",MPFR_RNDU,"2.0"); /* exp(2.0) */
321   check2("7.53428236571286402512e+34",MPFR_RNDZ,"8.03073567492226345621e+01");
322   check2("6.18784121531737948160e+19",MPFR_RNDZ,"4.55717030391710693493e+01");
323   check2("1.02560267603047283735e+00",MPFR_RNDD,"2.52804164149448735987e-02");
324   check2("7.53428236571286402512e+34",MPFR_RNDZ,"8.03073567492226345621e+01");
325   check2("1.42470900831881198052e+49",MPFR_RNDZ,"113.180637144887668910087086260318756103515625");
326 
327   check2("1.08013816255293777466e+11",MPFR_RNDN,"2.54055249841782604392e+01");
328   check2("6.72783635300509015581e-37",MPFR_RNDU,"-8.32893948416799503320e+01");
329   check2("2.25904918906057891180e-52",MPFR_RNDU,"-1.18919480823735682406e+02");
330   check2("1.48901209246462951085e+00",MPFR_RNDD,"3.98112874867437460668e-01");
331   check2("1.70322470467612341327e-01",MPFR_RNDN,"-1.77006175364294615626");
332   check2("1.94572026316065240791e+01",MPFR_RNDD,"2.96821731676437838842");
333   check2("4.01419512207026418764e+04",MPFR_RNDD,"1.06001772315501128218e+01");
334   check2("9.47077365236487591672e-04",MPFR_RNDZ,"-6.96212977303956748187e+00");
335   check2("3.95906157687589643802e-109",MPFR_RNDD,"-2.49605768114704119399e+02");
336   check2("2.73874914516503004113e-02",MPFR_RNDD,"-3.59766888618655977794e+00");
337   check2("9.18989072589566467669e-17",MPFR_RNDZ,"-3.69258425351464083519e+01");
338   check2("7706036453608191045959753324430048151991964994788917248.0",MPFR_RNDZ,"126.3815989984199177342816255986690521240234375");
339   check2("1.74827399630587801934e-23",MPFR_RNDZ,"-5.24008281254547156891e+01");
340   check2("4.35302958401482307665e+22",MPFR_RNDD,"5.21277441046519527390e+01");
341   check2("9.70791868689332915209e+00",MPFR_RNDD,"2.27294191194272210410e+00");
342   check2("2.22183639799464011100e-01",MPFR_RNDN,"-1.50425103275253957413e+00");
343   check2("2.27313466156682375540e+00",MPFR_RNDD,"8.21159787095675608448e-01");
344   check2("6.58057413965851156767e-01",MPFR_RNDZ,"-4.18463096196088235600e-01");
345   check2 ("7.34302197248998461006e+43",MPFR_RNDZ,"101.0049094695131799426235374994575977325439453125");
346   check2("6.09969788341579732815e+00",MPFR_RNDD,"1.80823924264386204363e+00");
347 
348   x_near_one ();
349 
350   test_generic (MPFR_PREC_MIN, 100, 40);
351 
352   data_check ("data/log", mpfr_log, "mpfr_log");
353   bad_cases (mpfr_log, mpfr_exp, "mpfr_log", 256, -30, 30, 4, 128, 800, 50);
354 
355  done:
356   tests_end_mpfr ();
357   return 0;
358 }
359