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