1/* Test file for mpfr_log.
2
3Copyright 1999, 2001-2023 Free Software Foundation, Inc.
4Contributed by the AriC and Caramba projects, INRIA.
5
6This file is part of the GNU MPFR Library.
7
8The GNU MPFR Library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as published by
10the Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
12
13The GNU MPFR Library is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16License for more details.
17
18You should have received a copy of the GNU Lesser General Public License
19along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23#include "mpfr-test.h"
24
25#ifdef CHECK_EXTERNAL
26static int
27test_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
48static void
49check2 (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
70static void
71check3 (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://perso.ens-lyon.fr/jean-michel.muller/Intro-to-TMD.htm
87*/
88
89static void
90check_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
173static void
174special (void)
175{
176  mpfr_t x, y;
177  int inex;
178  mpfr_exp_t emin, emax;
179  int r;
180
181  emin = mpfr_get_emin ();
182  emax = mpfr_get_emax ();
183
184  mpfr_init2 (x, 53);
185  mpfr_init2 (y, 53);
186
187  /* Check special case: An overflow in const_pi could occurs! */
188  set_emin (-125);
189  set_emax (128);
190  mpfr_set_prec (y, 24*2);
191  mpfr_set_prec (x, 24);
192  mpfr_set_str_binary (x, "0.111110101010101011110101E0");
193  test_log (y, x, MPFR_RNDN);
194  set_emin (emin);
195  set_emax (emax);
196
197  mpfr_set_prec (y, 53);
198  mpfr_set_prec (x, 53);
199  mpfr_set_ui (x, 3, MPFR_RNDD);
200  test_log (y, x, MPFR_RNDD);
201  if (mpfr_cmp_str1 (y, "1.09861228866810956"))
202    {
203      printf ("Error in mpfr_log(3) for MPFR_RNDD\n");
204      exit (1);
205    }
206
207  /* check large precision */
208  mpfr_set_prec (x, 3322);
209  mpfr_set_prec (y, 3322);
210  mpfr_set_ui (x, 3, MPFR_RNDN);
211  mpfr_sqrt (x, x, MPFR_RNDN);
212  test_log (y, x, MPFR_RNDN);
213
214  /* negative argument */
215  mpfr_set_si (x, -1, MPFR_RNDN);
216  test_log (y, x, MPFR_RNDN);
217  MPFR_ASSERTN(mpfr_nan_p (y));
218
219  /* infinite loop when  */
220  set_emax (128);
221  mpfr_set_prec (x, 251);
222  mpfr_set_prec (y, 251);
223  mpfr_set_str_binary (x, "0.10010111000000000001101E8");
224  /* x = 4947981/32768, log(x) ~ 5.017282... */
225  test_log (y, x, MPFR_RNDN);
226
227  set_emax (emax);
228
229  mpfr_set_ui (x, 0, MPFR_RNDN);
230  inex = test_log (y, x, MPFR_RNDN);
231  MPFR_ASSERTN (inex == 0);
232  MPFR_ASSERTN (mpfr_inf_p (y));
233  MPFR_ASSERTN (mpfr_sgn (y) < 0);
234
235  mpfr_set_ui (x, 0, MPFR_RNDN);
236  mpfr_neg (x, x, MPFR_RNDN);
237  inex = test_log (y, x, MPFR_RNDN);
238  MPFR_ASSERTN (inex == 0);
239  MPFR_ASSERTN (mpfr_inf_p (y));
240  MPFR_ASSERTN (mpfr_sgn (y) < 0);
241
242  /* check log(1) is +0 whatever the rounding mode */
243  mpfr_set_ui (x, 1, MPFR_RNDN);
244  RND_LOOP (r)
245    {
246      mpfr_clear_flags ();
247      inex = test_log (y, x, (mpfr_rnd_t) r);
248      MPFR_ASSERTN (__gmpfr_flags == 0);
249      MPFR_ASSERTN (inex == 0);
250      MPFR_ASSERTN (MPFR_IS_ZERO (y));
251      MPFR_ASSERTN (MPFR_IS_POS (y));
252    }
253
254  mpfr_clear (x);
255  mpfr_clear (y);
256}
257
258static void
259x_near_one (void)
260{
261  mpfr_t x, y;
262  int inex;
263
264  mpfr_init2 (x, 32);
265  mpfr_init2 (y, 16);
266
267  mpfr_set_ui (x, 1, MPFR_RNDN);
268  mpfr_nextbelow (x);
269  inex = mpfr_log (y, x, MPFR_RNDD);
270  if (mpfr_cmp_str (y, "-0.1000000000000001E-31", 2, MPFR_RNDN)
271      || inex >= 0)
272    {
273      printf ("Failure in x_near_one, got inex = %d and\ny = ", inex);
274      mpfr_dump (y);
275    }
276
277  mpfr_clears (x, y, (mpfr_ptr) 0);
278}
279
280#define TEST_FUNCTION test_log
281#define TEST_RANDOM_POS 8
282#include "tgeneric.c"
283
284int
285main (int argc, char *argv[])
286{
287  tests_start_mpfr ();
288
289  if (argc == 3 || argc == 4)
290    {   /* tlog x prec rnd */
291      check3 (argv[1], strtoul (argv[2], NULL, 10),
292              (argc == 4) ? (mpfr_rnd_t) atoi (argv[3]) : MPFR_RNDN);
293      goto done;
294    }
295
296  special ();
297  check_worst_cases();
298
299  check2("1.01979300812244555452", MPFR_RNDN, "1.95996734891603664741e-02");
300  check2("10.0",MPFR_RNDU,"2.30258509299404590110e+00");
301  check2("6.0",MPFR_RNDU,"1.79175946922805517936");
302  check2("1.0",MPFR_RNDZ,"0.0");
303  check2("62.0",MPFR_RNDU,"4.12713438504509166905");
304  check2("0.5",MPFR_RNDZ,"-6.93147180559945286226e-01");
305  check2("3.0",MPFR_RNDZ,"1.09861228866810956006e+00");
306  check2("234375765.0",MPFR_RNDU,"1.92724362186836231104e+01");
307  check2("8.0",MPFR_RNDZ,"2.07944154167983574765e+00");
308  check2("44.0",MPFR_RNDU,"3.78418963391826146392e+00");
309  check2("1.01979300812244555452", MPFR_RNDN, "1.95996734891603664741e-02");
310
311  /* bugs found by Vincent Lefe`vre */
312  check2("0.99999599881598921769", MPFR_RNDN, "-0.0000040011920155404072924737977900999652547398000024259090423583984375");
313  check2("9.99995576063808955247e-01",MPFR_RNDZ,"-4.42394597667932383816e-06");
314  check2("9.99993687357856209097e-01",MPFR_RNDN,"-6.31266206860017342601e-06");
315  check2("9.99995223520736886691e-01",MPFR_RNDN,"-4.77649067052670982220e-06");
316  check2("9.99993025794720935551e-01",MPFR_RNDN,"-6.97422959894716163837e-06");
317  check2("9.99987549017837484833e-01",MPFR_RNDN,"-1.24510596766369924330e-05");
318  check2("9.99985901426543311032e-01",MPFR_RNDN,"-1.40986728425098585229e-05");
319  check2("9.99986053947420794330e-01",MPFR_RNDN, "-0.000013946149826301084938555592540598837558718514628708362579345703125");
320  check2("9.99971938247442126979e-01",MPFR_RNDN,"-2.80621462962173414790e-05");
321
322  /* other bugs found by Vincent Lefe`vre */
323  check2("1.18615436389927785905e+77",MPFR_RNDN,"1.77469768607706015473e+02");
324  check2("9.48868723578399476187e+77",MPFR_RNDZ,"1.79549152432275803903e+02");
325  check2("2.31822210096938820854e+89",MPFR_RNDN,"2.05770873832573869322e+02");
326
327  /* further bugs found by Vincent Lefe`vre */
328  check2("9.99999989485669482647e-01",MPFR_RNDZ,"-1.05143305726283042331e-08");
329  check2("9.99999989237970177136e-01",MPFR_RNDZ,"-1.07620298807745377934e-08");
330  check2("9.99999989239339082125e-01",MPFR_RNDN,"-1.07606609757704445430e-08");
331
332  check2("7.3890560989306504",MPFR_RNDU,"2.0000000000000004"); /* exp(2.0) */
333  check2("7.3890560989306495",MPFR_RNDU,"2.0"); /* exp(2.0) */
334  check2("7.53428236571286402512e+34",MPFR_RNDZ,"8.03073567492226345621e+01");
335  check2("6.18784121531737948160e+19",MPFR_RNDZ,"4.55717030391710693493e+01");
336  check2("1.02560267603047283735e+00",MPFR_RNDD,"2.52804164149448735987e-02");
337  check2("7.53428236571286402512e+34",MPFR_RNDZ,"8.03073567492226345621e+01");
338  check2("1.42470900831881198052e+49",MPFR_RNDZ,"113.180637144887668910087086260318756103515625");
339
340  check2("1.08013816255293777466e+11",MPFR_RNDN,"2.54055249841782604392e+01");
341  check2("6.72783635300509015581e-37",MPFR_RNDU,"-8.32893948416799503320e+01");
342  check2("2.25904918906057891180e-52",MPFR_RNDU,"-1.18919480823735682406e+02");
343  check2("1.48901209246462951085e+00",MPFR_RNDD,"3.98112874867437460668e-01");
344  check2("1.70322470467612341327e-01",MPFR_RNDN,"-1.77006175364294615626");
345  check2("1.94572026316065240791e+01",MPFR_RNDD,"2.96821731676437838842");
346  check2("4.01419512207026418764e+04",MPFR_RNDD,"1.06001772315501128218e+01");
347  check2("9.47077365236487591672e-04",MPFR_RNDZ,"-6.96212977303956748187e+00");
348  check2("3.95906157687589643802e-109",MPFR_RNDD,"-2.49605768114704119399e+02");
349  check2("2.73874914516503004113e-02",MPFR_RNDD,"-3.59766888618655977794e+00");
350  check2("9.18989072589566467669e-17",MPFR_RNDZ,"-3.69258425351464083519e+01");
351  check2("7706036453608191045959753324430048151991964994788917248.0",MPFR_RNDZ,"126.3815989984199177342816255986690521240234375");
352  check2("1.74827399630587801934e-23",MPFR_RNDZ,"-5.24008281254547156891e+01");
353  check2("4.35302958401482307665e+22",MPFR_RNDD,"5.21277441046519527390e+01");
354  check2("9.70791868689332915209e+00",MPFR_RNDD,"2.27294191194272210410e+00");
355  check2("2.22183639799464011100e-01",MPFR_RNDN,"-1.50425103275253957413e+00");
356  check2("2.27313466156682375540e+00",MPFR_RNDD,"8.21159787095675608448e-01");
357  check2("6.58057413965851156767e-01",MPFR_RNDZ,"-4.18463096196088235600e-01");
358  check2 ("7.34302197248998461006e+43",MPFR_RNDZ,"101.0049094695131799426235374994575977325439453125");
359  check2("6.09969788341579732815e+00",MPFR_RNDD,"1.80823924264386204363e+00");
360
361  x_near_one ();
362
363  test_generic (MPFR_PREC_MIN, 100, 40);
364
365  data_check ("data/log", mpfr_log, "mpfr_log");
366  bad_cases (mpfr_log, mpfr_exp, "mpfr_log", 256, -30, 30, 4, 128, 800, 50);
367
368 done:
369  tests_end_mpfr ();
370  return 0;
371}
372