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