1 1.1 mrg /* Test file for mpfr_exp. 2 1.1 mrg 3 1.7 mrg Copyright 1999, 2001-2023 Free Software Foundation, Inc. 4 1.4 mrg Contributed by the AriC and Caramba projects, INRIA. 5 1.1 mrg 6 1.1 mrg This file is part of the GNU MPFR Library. 7 1.1 mrg 8 1.1 mrg The GNU MPFR Library is free software; you can redistribute it and/or modify 9 1.1 mrg it under the terms of the GNU Lesser General Public License as published by 10 1.1 mrg the Free Software Foundation; either version 3 of the License, or (at your 11 1.1 mrg option) any later version. 12 1.1 mrg 13 1.1 mrg The GNU MPFR Library is distributed in the hope that it will be useful, but 14 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16 1.1 mrg License for more details. 17 1.1 mrg 18 1.1 mrg You should have received a copy of the GNU Lesser General Public License 19 1.1 mrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20 1.6 mrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 21 1.1 mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 1.1 mrg 23 1.1 mrg #include "mpfr-test.h" 24 1.1 mrg 25 1.1 mrg #ifdef CHECK_EXTERNAL 26 1.1 mrg static int 27 1.1 mrg test_exp (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode) 28 1.1 mrg { 29 1.1 mrg int res; 30 1.1 mrg int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53; 31 1.1 mrg if (ok) 32 1.1 mrg { 33 1.1 mrg mpfr_print_raw (b); 34 1.1 mrg } 35 1.1 mrg res = mpfr_exp (a, b, rnd_mode); 36 1.1 mrg if (ok) 37 1.1 mrg { 38 1.1 mrg printf (" "); 39 1.1 mrg mpfr_print_raw (a); 40 1.1 mrg printf ("\n"); 41 1.1 mrg } 42 1.1 mrg return res; 43 1.1 mrg } 44 1.1 mrg #else 45 1.1 mrg #define test_exp mpfr_exp 46 1.1 mrg #endif 47 1.1 mrg 48 1.1 mrg /* returns the number of ulp of error */ 49 1.1 mrg static void 50 1.1 mrg check3 (const char *op, mpfr_rnd_t rnd, const char *res) 51 1.1 mrg { 52 1.1 mrg mpfr_t x, y; 53 1.1 mrg 54 1.1 mrg mpfr_inits2 (53, x, y, (mpfr_ptr) 0); 55 1.1 mrg /* y negative. If we forget to set the sign in mpfr_exp, we'll see it. */ 56 1.1 mrg mpfr_set_si (y, -1, MPFR_RNDN); 57 1.1 mrg mpfr_set_str1 (x, op); 58 1.1 mrg test_exp (y, x, rnd); 59 1.1 mrg if (mpfr_cmp_str1 (y, res) ) 60 1.1 mrg { 61 1.1 mrg printf ("mpfr_exp failed for x=%s, rnd=%s\n", 62 1.1 mrg op, mpfr_print_rnd_mode (rnd)); 63 1.1 mrg printf ("expected result is %s, got ", res); 64 1.1 mrg mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN); 65 1.1 mrg putchar('\n'); 66 1.1 mrg exit (1); 67 1.1 mrg } 68 1.1 mrg mpfr_clears (x, y, (mpfr_ptr) 0); 69 1.1 mrg } 70 1.1 mrg 71 1.1 mrg /* expx is the value of exp(X) rounded toward -infinity */ 72 1.1 mrg static void 73 1.1 mrg check_worst_case (const char *Xs, const char *expxs) 74 1.1 mrg { 75 1.1 mrg mpfr_t x, y; 76 1.1 mrg 77 1.1 mrg mpfr_inits2 (53, x, y, (mpfr_ptr) 0); 78 1.1 mrg mpfr_set_str1(x, Xs); 79 1.1 mrg test_exp(y, x, MPFR_RNDD); 80 1.1 mrg if (mpfr_cmp_str1 (y, expxs)) 81 1.1 mrg { 82 1.1 mrg printf ("exp(x) rounded toward -infinity is wrong\n"); 83 1.1 mrg exit(1); 84 1.1 mrg } 85 1.1 mrg mpfr_set_str1(x, Xs); 86 1.1 mrg test_exp(x, x, MPFR_RNDU); 87 1.1 mrg mpfr_nexttoinf (y); 88 1.1 mrg if (mpfr_cmp(x,y)) 89 1.1 mrg { 90 1.1 mrg printf ("exp(x) rounded toward +infinity is wrong\n"); 91 1.1 mrg exit(1); 92 1.1 mrg } 93 1.1 mrg mpfr_clears (x, y, (mpfr_ptr) 0); 94 1.1 mrg } 95 1.1 mrg 96 1.1 mrg /* worst cases communicated by Jean-Michel Muller and Vincent Lefevre */ 97 1.1 mrg static int 98 1.1 mrg check_worst_cases (void) 99 1.1 mrg { 100 1.1 mrg mpfr_t x; mpfr_t y; 101 1.1 mrg 102 1.1 mrg mpfr_init(x); 103 1.1 mrg mpfr_set_prec (x, 53); 104 1.1 mrg 105 1.1 mrg check_worst_case("4.44089209850062517562e-16", "1.00000000000000022204"); 106 1.1 mrg check_worst_case("6.39488462184069720009e-14", "1.00000000000006372680"); 107 1.1 mrg check_worst_case("1.84741111297455401935e-12", "1.00000000000184718907"); 108 1.1 mrg check_worst_case("1.76177628026265550074e-10", "1.00000000017617751702"); 109 1.1 mrg check3("1.76177628026265550074e-10", MPFR_RNDN, "1.00000000017617773906"); 110 1.1 mrg check_worst_case("7.54175277499595900852e-10", "1.00000000075417516676"); 111 1.1 mrg check3("7.54175277499595900852e-10", MPFR_RNDN, "1.00000000075417538881"); 112 1.1 mrg /* bug found by Vincent Lefe`vre on December 8, 1999 */ 113 1.1 mrg check3("-5.42410311287441459172e+02", MPFR_RNDN, "2.7176584868845723e-236"); 114 1.1 mrg /* further cases communicated by Vincent Lefe`vre on January 27, 2000 */ 115 1.1 mrg check3("-1.32920285897904911589e-10", MPFR_RNDN, "0.999999999867079769622"); 116 1.1 mrg check3("-1.44037948245738330735e-10", MPFR_RNDN, "0.9999999998559621072757"); 117 1.1 mrg check3("-1.66795910430705305937e-10", MPFR_RNDZ, "0.9999999998332040895832"); 118 1.1 mrg check3("-1.64310953745426656203e-10", MPFR_RNDN, "0.9999999998356891017792"); 119 1.1 mrg check3("-1.38323574826034659172e-10", MPFR_RNDZ, "0.9999999998616764251835"); 120 1.1 mrg check3("-1.23621668465115401498e-10", MPFR_RNDZ, "0.9999999998763783315425"); 121 1.1 mrg 122 1.1 mrg mpfr_set_prec (x, 601); 123 1.1 mrg mpfr_set_str (x, "0.88b6ba510e10450edc258748bc9dfdd466f21b47ed264cdf24aa8f64af1f3fad9ec2301d43c0743f534b5aa20091ff6d352df458ef1ba519811ef6f5b11853534fd8fa32764a0a6d2d0dd20@0", 16, MPFR_RNDZ); 124 1.1 mrg mpfr_init2 (y, 601); 125 1.1 mrg mpfr_exp_2 (y, x, MPFR_RNDD); 126 1.1 mrg mpfr_exp_3 (x, x, MPFR_RNDD); 127 1.1 mrg if (mpfr_cmp (x, y)) 128 1.1 mrg { 129 1.1 mrg printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=601\n"); 130 1.1 mrg printf ("mpfr_exp_2 gives "); 131 1.1 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 132 1.1 mrg printf ("\nmpfr_exp_3 gives "); 133 1.1 mrg mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); 134 1.1 mrg printf ("\n"); 135 1.1 mrg exit (1); 136 1.1 mrg } 137 1.1 mrg 138 1.1 mrg mpfr_set_prec (x, 13001); 139 1.1 mrg mpfr_set_prec (y, 13001); 140 1.1 mrg mpfr_urandomb (x, RANDS); 141 1.1 mrg mpfr_exp_3 (y, x, MPFR_RNDN); 142 1.1 mrg mpfr_exp_2 (x, x, MPFR_RNDN); 143 1.1 mrg if (mpfr_cmp (x, y)) 144 1.1 mrg { 145 1.1 mrg printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=13001\n"); 146 1.1 mrg exit (1); 147 1.1 mrg } 148 1.1 mrg 149 1.4 mrg mpfr_set_prec (x, 118); 150 1.4 mrg mpfr_set_str_binary (x, "0.1110010100011101010000111110011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E-86"); 151 1.4 mrg mpfr_set_prec (y, 118); 152 1.4 mrg mpfr_exp_2 (y, x, MPFR_RNDU); 153 1.4 mrg mpfr_exp_3 (x, x, MPFR_RNDU); 154 1.4 mrg if (mpfr_cmp (x, y)) 155 1.4 mrg { 156 1.4 mrg printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=118\n"); 157 1.4 mrg printf ("mpfr_exp_2 gives "); 158 1.4 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 159 1.4 mrg printf ("\nmpfr_exp_3 gives "); 160 1.4 mrg mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); 161 1.4 mrg printf ("\n"); 162 1.4 mrg exit (1); 163 1.4 mrg } 164 1.4 mrg 165 1.1 mrg mpfr_clear (x); 166 1.1 mrg mpfr_clear (y); 167 1.1 mrg return 0; 168 1.1 mrg } 169 1.1 mrg 170 1.1 mrg static void 171 1.1 mrg compare_exp2_exp3 (mpfr_prec_t p0, mpfr_prec_t p1) 172 1.1 mrg { 173 1.1 mrg mpfr_t x, y, z; 174 1.1 mrg mpfr_prec_t prec; 175 1.1 mrg mpfr_rnd_t rnd; 176 1.1 mrg 177 1.1 mrg mpfr_init (x); 178 1.1 mrg mpfr_init (y); 179 1.1 mrg mpfr_init (z); 180 1.1 mrg for (prec = p0; prec <= p1; prec ++) 181 1.1 mrg { 182 1.1 mrg mpfr_set_prec (x, prec); 183 1.1 mrg mpfr_set_prec (y, prec); 184 1.1 mrg mpfr_set_prec (z, prec); 185 1.2 drochner do 186 1.2 drochner mpfr_urandomb (x, RANDS); 187 1.2 drochner while (MPFR_IS_ZERO (x)); /* 0 is handled by mpfr_exp only */ 188 1.1 mrg rnd = RND_RAND (); 189 1.1 mrg mpfr_exp_2 (y, x, rnd); 190 1.1 mrg mpfr_exp_3 (z, x, rnd); 191 1.1 mrg if (mpfr_cmp (y,z)) 192 1.1 mrg { 193 1.1 mrg printf ("mpfr_exp_2 and mpfr_exp_3 disagree for rnd=%s and\nx=", 194 1.1 mrg mpfr_print_rnd_mode (rnd)); 195 1.5 mrg mpfr_dump (x); 196 1.1 mrg printf ("mpfr_exp_2 gives "); 197 1.5 mrg mpfr_dump (y); 198 1.1 mrg printf ("mpfr_exp_3 gives "); 199 1.5 mrg mpfr_dump (z); 200 1.1 mrg exit (1); 201 1.1 mrg } 202 1.1 mrg } 203 1.1 mrg 204 1.1 mrg mpfr_clear (x); 205 1.1 mrg mpfr_clear (y); 206 1.1 mrg mpfr_clear (z); 207 1.1 mrg } 208 1.1 mrg 209 1.1 mrg static void 210 1.1 mrg check_large (void) 211 1.1 mrg { 212 1.1 mrg mpfr_t x, z; 213 1.1 mrg mpfr_prec_t prec; 214 1.1 mrg 215 1.1 mrg /* bug found by Patrick Pe'lissier on 7 Jun 2004 */ 216 1.1 mrg prec = 203780; 217 1.1 mrg mpfr_init2 (x, prec); 218 1.1 mrg mpfr_init2 (z, prec); 219 1.1 mrg mpfr_set_ui (x, 3, MPFR_RNDN); 220 1.1 mrg mpfr_sqrt (x, x, MPFR_RNDN); 221 1.1 mrg mpfr_sub_ui (x, x, 1, MPFR_RNDN); 222 1.1 mrg mpfr_exp_3 (z, x, MPFR_RNDN); 223 1.1 mrg mpfr_clear (x); 224 1.1 mrg mpfr_clear (z); 225 1.1 mrg } 226 1.1 mrg 227 1.1 mrg #define TEST_FUNCTION test_exp 228 1.1 mrg #define TEST_RANDOM_EMIN -36 229 1.1 mrg #define TEST_RANDOM_EMAX 36 230 1.1 mrg #include "tgeneric.c" 231 1.1 mrg 232 1.1 mrg static void 233 1.1 mrg check_special (void) 234 1.1 mrg { 235 1.1 mrg mpfr_t x, y, z; 236 1.1 mrg mpfr_exp_t emin, emax; 237 1.1 mrg 238 1.1 mrg emin = mpfr_get_emin (); 239 1.1 mrg emax = mpfr_get_emax (); 240 1.1 mrg 241 1.1 mrg mpfr_init (x); 242 1.1 mrg mpfr_init (y); 243 1.1 mrg mpfr_init (z); 244 1.1 mrg 245 1.1 mrg /* check exp(NaN) = NaN */ 246 1.1 mrg mpfr_set_nan (x); 247 1.1 mrg test_exp (y, x, MPFR_RNDN); 248 1.1 mrg if (!mpfr_nan_p (y)) 249 1.1 mrg { 250 1.1 mrg printf ("Error for exp(NaN)\n"); 251 1.1 mrg exit (1); 252 1.1 mrg } 253 1.1 mrg 254 1.1 mrg /* check exp(+inf) = +inf */ 255 1.1 mrg mpfr_set_inf (x, 1); 256 1.1 mrg test_exp (y, x, MPFR_RNDN); 257 1.1 mrg if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) 258 1.1 mrg { 259 1.1 mrg printf ("Error for exp(+inf)\n"); 260 1.1 mrg exit (1); 261 1.1 mrg } 262 1.1 mrg 263 1.1 mrg /* check exp(-inf) = +0 */ 264 1.1 mrg mpfr_set_inf (x, -1); 265 1.1 mrg test_exp (y, x, MPFR_RNDN); 266 1.5 mrg if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y)) 267 1.1 mrg { 268 1.1 mrg printf ("Error for exp(-inf)\n"); 269 1.1 mrg exit (1); 270 1.1 mrg } 271 1.1 mrg 272 1.1 mrg /* Check overflow. Corner case of mpfr_exp_2 */ 273 1.1 mrg mpfr_set_prec (x, 64); 274 1.7 mrg set_emax (MPFR_EMAX_DEFAULT); 275 1.7 mrg set_emin (MPFR_EMIN_DEFAULT); 276 1.1 mrg mpfr_set_str (x, 277 1.1 mrg "0.1011000101110010000101111111010100001100000001110001100111001101E30", 278 1.1 mrg 2, MPFR_RNDN); 279 1.1 mrg mpfr_exp (x, x, MPFR_RNDD); 280 1.1 mrg if (mpfr_cmp_str (x, 281 1.1 mrg ".1111111111111111111111111111111111111111111111111111111111111111E1073741823", 282 1.1 mrg 2, MPFR_RNDN) != 0) 283 1.1 mrg { 284 1.1 mrg printf ("Wrong overflow detection in mpfr_exp\n"); 285 1.1 mrg mpfr_dump (x); 286 1.1 mrg exit (1); 287 1.1 mrg } 288 1.1 mrg /* Check underflow. Corner case of mpfr_exp_2 */ 289 1.1 mrg mpfr_set_str (x, 290 1.1 mrg "-0.1011000101110010000101111111011111010001110011110111100110101100E30", 291 1.1 mrg 2, MPFR_RNDN); 292 1.1 mrg mpfr_exp (x, x, MPFR_RNDN); 293 1.1 mrg if (mpfr_cmp_str (x, "0.1E-1073741823", 2, MPFR_RNDN) != 0) 294 1.1 mrg { 295 1.1 mrg printf ("Wrong underflow (1) detection in mpfr_exp\n"); 296 1.1 mrg mpfr_dump (x); 297 1.1 mrg exit (1); 298 1.1 mrg } 299 1.1 mrg mpfr_set_str (x, 300 1.1 mrg "-0.1011001101110010000101111111011111010001110011110111100110111101E30", 301 1.1 mrg 2, MPFR_RNDN); 302 1.1 mrg mpfr_exp (x, x, MPFR_RNDN); 303 1.1 mrg if (mpfr_cmp_ui (x, 0) != 0) 304 1.1 mrg { 305 1.1 mrg printf ("Wrong underflow (2) detection in mpfr_exp\n"); 306 1.1 mrg mpfr_dump (x); 307 1.1 mrg exit (1); 308 1.1 mrg } 309 1.1 mrg /* Check overflow. Corner case of mpfr_exp_3 */ 310 1.1 mrg if (MPFR_PREC_MAX >= MPFR_EXP_THRESHOLD + 10 && MPFR_PREC_MAX >= 64) 311 1.1 mrg { 312 1.1 mrg /* this ensures that for small MPFR_EXP_THRESHOLD, the following 313 1.1 mrg mpfr_set_str conversion is exact */ 314 1.1 mrg mpfr_set_prec (x, (MPFR_EXP_THRESHOLD + 10 > 64) 315 1.1 mrg ? MPFR_EXP_THRESHOLD + 10 : 64); 316 1.1 mrg mpfr_set_str (x, 317 1.1 mrg "0.1011000101110010000101111111010100001100000001110001100111001101E30", 318 1.1 mrg 2, MPFR_RNDN); 319 1.1 mrg mpfr_clear_overflow (); 320 1.1 mrg mpfr_exp (x, x, MPFR_RNDD); 321 1.1 mrg if (!mpfr_overflow_p ()) 322 1.1 mrg { 323 1.1 mrg printf ("Wrong overflow detection in mpfr_exp_3\n"); 324 1.1 mrg mpfr_dump (x); 325 1.1 mrg exit (1); 326 1.1 mrg } 327 1.1 mrg /* Check underflow. Corner case of mpfr_exp_3 */ 328 1.1 mrg mpfr_set_str (x, 329 1.1 mrg "-0.1011000101110010000101111111011111010001110011110111100110101100E30", 330 1.1 mrg 2, MPFR_RNDN); 331 1.1 mrg mpfr_clear_underflow (); 332 1.1 mrg mpfr_exp (x, x, MPFR_RNDN); 333 1.1 mrg if (!mpfr_underflow_p ()) 334 1.1 mrg { 335 1.1 mrg printf ("Wrong underflow detection in mpfr_exp_3\n"); 336 1.1 mrg mpfr_dump (x); 337 1.1 mrg exit (1); 338 1.1 mrg } 339 1.1 mrg mpfr_set_prec (x, 53); 340 1.1 mrg } 341 1.1 mrg 342 1.1 mrg /* check overflow */ 343 1.1 mrg set_emax (10); 344 1.1 mrg mpfr_set_ui (x, 7, MPFR_RNDN); 345 1.1 mrg test_exp (y, x, MPFR_RNDN); 346 1.1 mrg if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) 347 1.1 mrg { 348 1.1 mrg printf ("Error for exp(7) for emax=10\n"); 349 1.1 mrg exit (1); 350 1.1 mrg } 351 1.1 mrg set_emax (emax); 352 1.1 mrg 353 1.1 mrg /* check underflow */ 354 1.1 mrg set_emin (-10); 355 1.1 mrg mpfr_set_si (x, -9, MPFR_RNDN); 356 1.1 mrg test_exp (y, x, MPFR_RNDN); 357 1.5 mrg if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y)) 358 1.1 mrg { 359 1.1 mrg printf ("Error for exp(-9) for emin=-10\n"); 360 1.1 mrg printf ("Expected +0\n"); 361 1.5 mrg printf ("Got "); mpfr_dump (y); 362 1.1 mrg exit (1); 363 1.1 mrg } 364 1.1 mrg set_emin (emin); 365 1.1 mrg 366 1.1 mrg /* check case EXP(x) < -precy */ 367 1.1 mrg mpfr_set_prec (y, 2); 368 1.1 mrg mpfr_set_str_binary (x, "-0.1E-3"); 369 1.1 mrg test_exp (y, x, MPFR_RNDD); 370 1.1 mrg if (mpfr_cmp_ui_2exp (y, 3, -2)) 371 1.1 mrg { 372 1.1 mrg printf ("Error for exp(-1/16), prec=2, RNDD\n"); 373 1.1 mrg printf ("expected 0.11, got "); 374 1.1 mrg mpfr_dump (y); 375 1.1 mrg exit (1); 376 1.1 mrg } 377 1.1 mrg test_exp (y, x, MPFR_RNDZ); 378 1.1 mrg if (mpfr_cmp_ui_2exp (y, 3, -2)) 379 1.1 mrg { 380 1.1 mrg printf ("Error for exp(-1/16), prec=2, RNDZ\n"); 381 1.1 mrg printf ("expected 0.11, got "); 382 1.1 mrg mpfr_dump (y); 383 1.1 mrg exit (1); 384 1.1 mrg } 385 1.1 mrg mpfr_set_str_binary (x, "0.1E-3"); 386 1.1 mrg test_exp (y, x, MPFR_RNDN); 387 1.1 mrg if (mpfr_cmp_ui (y, 1)) 388 1.1 mrg { 389 1.1 mrg printf ("Error for exp(1/16), prec=2, RNDN\n"); 390 1.1 mrg exit (1); 391 1.1 mrg } 392 1.1 mrg test_exp (y, x, MPFR_RNDU); 393 1.1 mrg if (mpfr_cmp_ui_2exp (y, 3, -1)) 394 1.1 mrg { 395 1.1 mrg printf ("Error for exp(1/16), prec=2, RNDU\n"); 396 1.1 mrg exit (1); 397 1.1 mrg } 398 1.1 mrg 399 1.1 mrg /* bug reported by Franky Backeljauw, 28 Mar 2003 */ 400 1.1 mrg mpfr_set_prec (x, 53); 401 1.1 mrg mpfr_set_prec (y, 53); 402 1.1 mrg mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28"); 403 1.1 mrg test_exp (y, x, MPFR_RNDN); 404 1.1 mrg 405 1.1 mrg mpfr_set_prec (x, 153); 406 1.1 mrg mpfr_set_prec (z, 153); 407 1.1 mrg mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28"); 408 1.1 mrg test_exp (z, x, MPFR_RNDN); 409 1.1 mrg mpfr_prec_round (z, 53, MPFR_RNDN); 410 1.1 mrg 411 1.1 mrg if (mpfr_cmp (y, z)) 412 1.1 mrg { 413 1.1 mrg printf ("Error in mpfr_exp for large argument\n"); 414 1.1 mrg exit (1); 415 1.1 mrg } 416 1.1 mrg 417 1.1 mrg /* corner cases in mpfr_exp_3 */ 418 1.1 mrg mpfr_set_prec (x, 2); 419 1.1 mrg mpfr_set_ui (x, 1, MPFR_RNDN); 420 1.1 mrg mpfr_set_prec (y, 2); 421 1.1 mrg mpfr_exp_3 (y, x, MPFR_RNDN); 422 1.1 mrg 423 1.1 mrg /* Check some little things about overflow detection */ 424 1.1 mrg set_emin (-125); 425 1.1 mrg set_emax (128); 426 1.1 mrg mpfr_set_prec (x, 107); 427 1.1 mrg mpfr_set_prec (y, 107); 428 1.1 mrg mpfr_set_str_binary (x, "0.11110000000000000000000000000000000000000000000" 429 1.1 mrg "0000000000000000000000000000000000000000000000000000" 430 1.1 mrg "00000000E4"); 431 1.1 mrg test_exp (y, x, MPFR_RNDN); 432 1.1 mrg if (mpfr_cmp_str (y, "0.11000111100001100110010101111101011010010101010000" 433 1.1 mrg "1101110111100010111001011111111000110111001011001101010" 434 1.1 mrg "01E22", 2, MPFR_RNDN)) 435 1.1 mrg { 436 1.1 mrg printf ("Special overflow error (1)\n"); 437 1.1 mrg mpfr_dump (y); 438 1.1 mrg exit (1); 439 1.1 mrg } 440 1.1 mrg 441 1.1 mrg set_emin (emin); 442 1.1 mrg set_emax (emax); 443 1.1 mrg 444 1.1 mrg /* Check for overflow producing a segfault with HUGE exponent */ 445 1.1 mrg mpfr_set_ui (x, 3, MPFR_RNDN); 446 1.1 mrg mpfr_mul_2ui (x, x, 32, MPFR_RNDN); 447 1.1 mrg test_exp (y, x, MPFR_RNDN); /* Can't test return value: May overflow or not*/ 448 1.1 mrg 449 1.1 mrg /* Bug due to wrong approximation of (x)/log2 */ 450 1.1 mrg mpfr_set_prec (x, 163); 451 1.1 mrg 452 1.1 mrg mpfr_set_str (x, "-4.28ac8fceeadcda06bb56359017b1c81b85b392e7", 16, 453 1.1 mrg MPFR_RNDN); 454 1.1 mrg mpfr_exp (x, x, MPFR_RNDN); 455 1.1 mrg if (mpfr_cmp_str (x, "3.fffffffffffffffffffffffffffffffffffffffe8@-2", 456 1.1 mrg 16, MPFR_RNDN)) 457 1.1 mrg { 458 1.1 mrg printf ("Error for x= -4.28ac8fceeadcda06bb56359017b1c81b85b392e7"); 459 1.1 mrg printf ("expected 3.fffffffffffffffffffffffffffffffffffffffe8@-2"); 460 1.1 mrg printf ("Got "); 461 1.1 mrg mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); 462 1.1 mrg } 463 1.1 mrg 464 1.1 mrg /* bug found by Guillaume Melquiond, 13 Sep 2005 */ 465 1.1 mrg mpfr_set_prec (x, 53); 466 1.1 mrg mpfr_set_str_binary (x, "-1E-400"); 467 1.1 mrg mpfr_exp (x, x, MPFR_RNDZ); 468 1.1 mrg if (mpfr_cmp_ui (x, 1) == 0) 469 1.1 mrg { 470 1.1 mrg printf ("Error for exp(-2^(-400))\n"); 471 1.1 mrg exit (1); 472 1.1 mrg } 473 1.1 mrg 474 1.1 mrg mpfr_clear (x); 475 1.1 mrg mpfr_clear (y); 476 1.1 mrg mpfr_clear (z); 477 1.1 mrg } 478 1.1 mrg 479 1.1 mrg /* check sign of inexact flag */ 480 1.1 mrg static void 481 1.1 mrg check_inexact (void) 482 1.1 mrg { 483 1.1 mrg mpfr_t x, y; 484 1.1 mrg int inexact; 485 1.1 mrg 486 1.1 mrg mpfr_init2 (x, 53); 487 1.1 mrg mpfr_init2 (y, 53); 488 1.1 mrg 489 1.1 mrg mpfr_set_str_binary (x, 490 1.1 mrg "1.0000000000001001000110100100101000001101101011100101e2"); 491 1.1 mrg inexact = test_exp (y, x, MPFR_RNDN); 492 1.1 mrg if (inexact <= 0) 493 1.1 mrg { 494 1.1 mrg printf ("Wrong inexact flag (Got %d instead of 1)\n", inexact); 495 1.1 mrg exit (1); 496 1.1 mrg } 497 1.1 mrg 498 1.1 mrg mpfr_clear (x); 499 1.1 mrg mpfr_clear (y); 500 1.1 mrg } 501 1.1 mrg 502 1.1 mrg static void 503 1.1 mrg check_exp10(void) 504 1.1 mrg { 505 1.1 mrg mpfr_t x; 506 1.1 mrg int inexact; 507 1.1 mrg 508 1.1 mrg mpfr_init2 (x, 200); 509 1.1 mrg mpfr_set_ui(x, 4, MPFR_RNDN); 510 1.1 mrg 511 1.1 mrg inexact = mpfr_exp10 (x, x, MPFR_RNDN); 512 1.1 mrg if (mpfr_cmp_ui(x, 10*10*10*10)) 513 1.1 mrg { 514 1.1 mrg printf ("exp10: Wrong returned value\n"); 515 1.1 mrg exit (1); 516 1.1 mrg } 517 1.1 mrg if (inexact != 0) 518 1.1 mrg { 519 1.1 mrg printf ("exp10: Wrong inexact flag\n"); 520 1.1 mrg exit (1); 521 1.1 mrg } 522 1.1 mrg 523 1.1 mrg mpfr_clear (x); 524 1.1 mrg } 525 1.1 mrg 526 1.1 mrg static void 527 1.1 mrg overflowed_exp0 (void) 528 1.1 mrg { 529 1.1 mrg mpfr_t x, y; 530 1.1 mrg int emax, i, inex, rnd, err = 0; 531 1.1 mrg mpfr_exp_t old_emax; 532 1.1 mrg 533 1.1 mrg old_emax = mpfr_get_emax (); 534 1.1 mrg 535 1.1 mrg mpfr_init2 (x, 8); 536 1.1 mrg mpfr_init2 (y, 8); 537 1.1 mrg 538 1.1 mrg for (emax = -1; emax <= 0; emax++) 539 1.1 mrg { 540 1.1 mrg mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN); 541 1.1 mrg mpfr_nextbelow (y); 542 1.1 mrg set_emax (emax); /* 1 is not representable. */ 543 1.1 mrg /* and if emax < 0, 1 - eps is not representable either. */ 544 1.1 mrg for (i = -1; i <= 1; i++) 545 1.1 mrg RND_LOOP (rnd) 546 1.5 mrg { 547 1.5 mrg mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN); 548 1.5 mrg mpfr_clear_flags (); 549 1.5 mrg inex = mpfr_exp (x, x, (mpfr_rnd_t) rnd); 550 1.5 mrg if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) && 551 1.5 mrg ! mpfr_overflow_p ()) 552 1.5 mrg { 553 1.5 mrg printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n" 554 1.5 mrg " The overflow flag is not set.\n", 555 1.5 mrg i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 556 1.5 mrg err = 1; 557 1.5 mrg } 558 1.5 mrg if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) 559 1.5 mrg { 560 1.5 mrg if (inex >= 0) 561 1.5 mrg { 562 1.5 mrg printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n" 563 1.5 mrg " The inexact value must be negative.\n", 564 1.5 mrg i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 565 1.5 mrg err = 1; 566 1.5 mrg } 567 1.5 mrg if (! mpfr_equal_p (x, y)) 568 1.5 mrg { 569 1.5 mrg printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n" 570 1.5 mrg " Got ", i, 571 1.5 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 572 1.5 mrg mpfr_dump (x); 573 1.5 mrg printf (" instead of 0.11111111E%d.\n", emax); 574 1.5 mrg err = 1; 575 1.5 mrg } 576 1.5 mrg } 577 1.5 mrg else if (rnd != MPFR_RNDF) 578 1.5 mrg { 579 1.5 mrg if (inex <= 0) 580 1.5 mrg { 581 1.5 mrg printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n" 582 1.5 mrg " The inexact value must be positive.\n", 583 1.5 mrg i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 584 1.5 mrg err = 1; 585 1.5 mrg } 586 1.5 mrg if (! (mpfr_inf_p (x) && MPFR_IS_POS (x))) 587 1.5 mrg { 588 1.5 mrg printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n" 589 1.5 mrg " Got ", i, 590 1.5 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 591 1.5 mrg mpfr_dump (x); 592 1.5 mrg printf (" instead of +Inf.\n"); 593 1.5 mrg err = 1; 594 1.5 mrg } 595 1.5 mrg } 596 1.5 mrg } 597 1.1 mrg set_emax (old_emax); 598 1.1 mrg } 599 1.1 mrg 600 1.1 mrg if (err) 601 1.1 mrg exit (1); 602 1.1 mrg mpfr_clear (x); 603 1.1 mrg mpfr_clear (y); 604 1.1 mrg } 605 1.1 mrg 606 1.1 mrg /* This bug occurs in mpfr_exp_2 on a Linux-64 machine, r5475. */ 607 1.1 mrg static void 608 1.1 mrg bug20080731 (void) 609 1.1 mrg { 610 1.1 mrg mpfr_exp_t emin; 611 1.1 mrg mpfr_t x, y1, y2; 612 1.1 mrg mpfr_prec_t prec = 64; 613 1.1 mrg 614 1.1 mrg emin = mpfr_get_emin (); 615 1.1 mrg set_emin (MPFR_EMIN_MIN); 616 1.1 mrg 617 1.1 mrg mpfr_init2 (x, 200); 618 1.1 mrg mpfr_set_str (x, "-2.c5c85fdf473de6af278ece700fcbdabd03cd0cb9ca62d8b62c@7", 619 1.1 mrg 16, MPFR_RNDN); 620 1.1 mrg 621 1.6 mrg /* exp(x) is just below 0xf.fffffffffffffffp-1073741828 */ 622 1.6 mrg 623 1.1 mrg mpfr_init2 (y1, prec); 624 1.1 mrg mpfr_exp (y1, x, MPFR_RNDU); 625 1.1 mrg 626 1.1 mrg /* Compute the result with a higher internal precision. */ 627 1.1 mrg mpfr_init2 (y2, 300); 628 1.1 mrg mpfr_exp (y2, x, MPFR_RNDU); 629 1.1 mrg mpfr_prec_round (y2, prec, MPFR_RNDU); 630 1.1 mrg 631 1.1 mrg if (mpfr_cmp0 (y1, y2) != 0) 632 1.1 mrg { 633 1.1 mrg printf ("Error in bug20080731\nExpected "); 634 1.6 mrg mpfr_dump (y2); 635 1.1 mrg printf ("\nGot "); 636 1.6 mrg mpfr_dump (y1); 637 1.1 mrg printf ("\n"); 638 1.1 mrg exit (1); 639 1.1 mrg } 640 1.1 mrg 641 1.1 mrg mpfr_clears (x, y1, y2, (mpfr_ptr) 0); 642 1.1 mrg set_emin (emin); 643 1.1 mrg } 644 1.1 mrg 645 1.1 mrg /* Emulate mpfr_exp with mpfr_exp_3 in the general case. */ 646 1.1 mrg static int 647 1.1 mrg exp_3 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode) 648 1.1 mrg { 649 1.1 mrg int inexact; 650 1.1 mrg 651 1.1 mrg inexact = mpfr_exp_3 (y, x, rnd_mode); 652 1.1 mrg return mpfr_check_range (y, inexact, rnd_mode); 653 1.1 mrg } 654 1.1 mrg 655 1.1 mrg static void 656 1.1 mrg underflow_up (int extended_emin) 657 1.1 mrg { 658 1.1 mrg mpfr_t minpos, x, y, t, t2; 659 1.1 mrg int precx, precy; 660 1.1 mrg int inex; 661 1.1 mrg int rnd; 662 1.1 mrg int e3; 663 1.1 mrg int i, j; 664 1.1 mrg 665 1.1 mrg mpfr_init2 (minpos, 2); 666 1.1 mrg mpfr_set_ui (minpos, 0, MPFR_RNDN); 667 1.1 mrg mpfr_nextabove (minpos); 668 1.1 mrg 669 1.1 mrg /* Let's test values near the underflow boundary. 670 1.1 mrg * 671 1.1 mrg * Minimum representable positive number: minpos = 2^(emin - 1). 672 1.1 mrg * Let's choose an MPFR number x = log(minpos) + eps, with |eps| small 673 1.1 mrg * (note: eps cannot be 0, and cannot be a rational number either). 674 1.1 mrg * Then exp(x) = minpos * exp(eps) ~= minpos * (1 + eps + eps^2). 675 1.1 mrg * We will compute y = rnd(exp(x)) in some rounding mode, precision p. 676 1.1 mrg * 1. If eps > 0, then in any rounding mode: 677 1.1 mrg * rnd(exp(x)) >= minpos and no underflow. 678 1.1 mrg * So, let's take x1 = rndu(log(minpos)) in some precision. 679 1.1 mrg * 2. If eps < 0, then exp(x) < minpos and the result will be either 0 680 1.1 mrg * or minpos. An underflow always occurs in MPFR_RNDZ and MPFR_RNDD, 681 1.1 mrg * but not necessarily in MPFR_RNDN and MPFR_RNDU (this is underflow 682 1.1 mrg * after rounding in an unbounded exponent range). If -a < eps < -b, 683 1.1 mrg * minpos * (1 - a) < exp(x) < minpos * (1 - b + b^2). 684 1.1 mrg * - If eps > -2^(-p), no underflow in MPFR_RNDU. 685 1.1 mrg * - If eps > -2^(-p-1), no underflow in MPFR_RNDN. 686 1.1 mrg * - If eps < - (2^(-p-1) + 2^(-2p-1)), underflow in MPFR_RNDN. 687 1.1 mrg * - If eps < - (2^(-p) + 2^(-2p+1)), underflow in MPFR_RNDU. 688 1.1 mrg * - In MPFR_RNDN, result is minpos iff exp(eps) > 1/2, i.e. 689 1.1 mrg * - log(2) < eps < ... 690 1.1 mrg * 691 1.1 mrg * Moreover, since precy < MPFR_EXP_THRESHOLD (to avoid tests that take 692 1.1 mrg * too much time), mpfr_exp() always selects mpfr_exp_2(); so, we need 693 1.1 mrg * to test mpfr_exp_3() too. This will be done via the e3 variable: 694 1.1 mrg * e3 = 0: mpfr_exp(), thus mpfr_exp_2(). 695 1.1 mrg * e3 = 1: mpfr_exp_3(), via the exp_3() wrapper. 696 1.1 mrg * i.e.: inex = e3 ? exp_3 (y, x, rnd) : mpfr_exp (y, x, rnd); 697 1.1 mrg */ 698 1.1 mrg 699 1.1 mrg /* Case eps > 0. In revision 5461 (trunk) on a 64-bit Linux machine: 700 1.1 mrg * Incorrect flags in underflow_up, eps > 0, MPFR_RNDN and extended emin 701 1.1 mrg * for precx = 96, precy = 16, mpfr_exp_3 702 1.1 mrg * Got 9 instead of 8. 703 1.1 mrg * Note: testing this case in several precisions for x and y introduces 704 1.1 mrg * some useful random. Indeed, the bug is not always triggered. 705 1.1 mrg * Fixed in r5469. 706 1.1 mrg */ 707 1.1 mrg for (precx = 16; precx <= 128; precx += 16) 708 1.1 mrg { 709 1.1 mrg mpfr_init2 (x, precx); 710 1.1 mrg mpfr_log (x, minpos, MPFR_RNDU); 711 1.1 mrg for (precy = 16; precy <= 128; precy += 16) 712 1.1 mrg { 713 1.1 mrg mpfr_init2 (y, precy); 714 1.1 mrg 715 1.1 mrg for (e3 = 0; e3 <= 1; e3++) 716 1.1 mrg { 717 1.1 mrg RND_LOOP (rnd) 718 1.1 mrg { 719 1.1 mrg int err = 0; 720 1.1 mrg 721 1.1 mrg mpfr_clear_flags (); 722 1.1 mrg inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd) 723 1.1 mrg : mpfr_exp (y, x, (mpfr_rnd_t) rnd); 724 1.5 mrg /* for MPFR_RNDF, the inexact flag is undefined */ 725 1.5 mrg if (__gmpfr_flags != MPFR_FLAGS_INEXACT && rnd != MPFR_RNDF) 726 1.1 mrg { 727 1.1 mrg printf ("Incorrect flags in underflow_up, eps > 0, %s", 728 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 729 1.1 mrg if (extended_emin) 730 1.1 mrg printf (" and extended emin"); 731 1.1 mrg printf ("\nfor precx = %d, precy = %d, %s\n", 732 1.1 mrg precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp"); 733 1.5 mrg printf ("x="); mpfr_dump (x); 734 1.5 mrg printf ("y="); mpfr_dump (y); 735 1.5 mrg printf ("Got %u instead of %u.\n", 736 1.5 mrg (unsigned int) __gmpfr_flags, 737 1.1 mrg (unsigned int) MPFR_FLAGS_INEXACT); 738 1.1 mrg err = 1; 739 1.1 mrg } 740 1.1 mrg if (mpfr_cmp0 (y, minpos) < 0) 741 1.1 mrg { 742 1.1 mrg printf ("Incorrect result in underflow_up, eps > 0, %s", 743 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 744 1.1 mrg if (extended_emin) 745 1.1 mrg printf (" and extended emin"); 746 1.1 mrg printf ("\nfor precx = %d, precy = %d, %s\n", 747 1.1 mrg precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp"); 748 1.1 mrg mpfr_dump (y); 749 1.1 mrg err = 1; 750 1.1 mrg } 751 1.5 mrg /* for MPFR_RNDF, the ternary value is undefined */ 752 1.5 mrg if (rnd != MPFR_RNDF) 753 1.5 mrg MPFR_ASSERTN (inex != 0); 754 1.1 mrg if (rnd == MPFR_RNDD || rnd == MPFR_RNDZ) 755 1.1 mrg MPFR_ASSERTN (inex < 0); 756 1.1 mrg if (rnd == MPFR_RNDU) 757 1.1 mrg MPFR_ASSERTN (inex > 0); 758 1.1 mrg if (err) 759 1.1 mrg exit (1); 760 1.1 mrg } 761 1.1 mrg } 762 1.1 mrg 763 1.1 mrg mpfr_clear (y); 764 1.1 mrg } 765 1.1 mrg mpfr_clear (x); 766 1.1 mrg } 767 1.1 mrg 768 1.1 mrg /* Case - log(2) < eps < 0 in MPFR_RNDN, starting with small-precision x; 769 1.1 mrg * only check the result and the ternary value. 770 1.1 mrg * Previous to r5453 (trunk), on 32-bit and 64-bit machines, this fails 771 1.1 mrg * for precx = 65 and precy = 16, e.g.: 772 1.1 mrg * exp_2.c:264: assertion failed: ... 773 1.1 mrg * because mpfr_sub (r, x, r, MPFR_RNDU); yields a null value. This is 774 1.1 mrg * fixed in r5453 by going to next Ziv's iteration. 775 1.1 mrg */ 776 1.1 mrg for (precx = sizeof(mpfr_exp_t) * CHAR_BIT + 1; precx <= 81; precx += 8) 777 1.1 mrg { 778 1.1 mrg mpfr_init2 (x, precx); 779 1.1 mrg mpfr_log (x, minpos, MPFR_RNDD); /* |ulp| <= 1/2 */ 780 1.1 mrg for (precy = 16; precy <= 128; precy += 16) 781 1.1 mrg { 782 1.1 mrg mpfr_init2 (y, precy); 783 1.1 mrg inex = mpfr_exp (y, x, MPFR_RNDN); 784 1.1 mrg if (inex <= 0 || mpfr_cmp0 (y, minpos) != 0) 785 1.1 mrg { 786 1.1 mrg printf ("Error in underflow_up, - log(2) < eps < 0"); 787 1.1 mrg if (extended_emin) 788 1.1 mrg printf (" and extended emin"); 789 1.1 mrg printf (" for prec = %d\nExpected ", precy); 790 1.1 mrg mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN); 791 1.1 mrg printf (" (minimum positive MPFR number) and inex > 0\nGot "); 792 1.1 mrg mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); 793 1.1 mrg printf ("\nwith inex = %d\n", inex); 794 1.1 mrg exit (1); 795 1.1 mrg } 796 1.1 mrg mpfr_clear (y); 797 1.1 mrg } 798 1.1 mrg mpfr_clear (x); 799 1.1 mrg } 800 1.1 mrg 801 1.1 mrg /* Cases eps ~ -2^(-p) and eps ~ -2^(-p-1). More precisely, 802 1.1 mrg * _ for j = 0, eps > -2^(-(p+i)), 803 1.1 mrg * _ for j = 1, eps < - (2^(-(p+i)) + 2^(1-2(p+i))), 804 1.1 mrg * where i = 0 or 1. 805 1.1 mrg */ 806 1.1 mrg mpfr_inits2 (2, t, t2, (mpfr_ptr) 0); 807 1.1 mrg for (precy = 16; precy <= 128; precy += 16) 808 1.1 mrg { 809 1.1 mrg mpfr_set_ui_2exp (t, 1, - precy, MPFR_RNDN); /* 2^(-p) */ 810 1.1 mrg mpfr_set_ui_2exp (t2, 1, 1 - 2 * precy, MPFR_RNDN); /* 2^(-2p+1) */ 811 1.1 mrg precx = sizeof(mpfr_exp_t) * CHAR_BIT + 2 * precy + 8; 812 1.1 mrg mpfr_init2 (x, precx); 813 1.1 mrg mpfr_init2 (y, precy); 814 1.1 mrg for (i = 0; i <= 1; i++) 815 1.1 mrg { 816 1.1 mrg for (j = 0; j <= 1; j++) 817 1.1 mrg { 818 1.1 mrg if (j == 0) 819 1.1 mrg { 820 1.1 mrg /* Case eps > -2^(-(p+i)). */ 821 1.1 mrg mpfr_log (x, minpos, MPFR_RNDU); 822 1.1 mrg } 823 1.1 mrg else /* j == 1 */ 824 1.1 mrg { 825 1.1 mrg /* Case eps < - (2^(-(p+i)) + 2^(1-2(p+i))). */ 826 1.1 mrg mpfr_log (x, minpos, MPFR_RNDD); 827 1.1 mrg inex = mpfr_sub (x, x, t2, MPFR_RNDN); 828 1.1 mrg MPFR_ASSERTN (inex == 0); 829 1.1 mrg } 830 1.1 mrg inex = mpfr_sub (x, x, t, MPFR_RNDN); 831 1.1 mrg MPFR_ASSERTN (inex == 0); 832 1.1 mrg 833 1.1 mrg RND_LOOP (rnd) 834 1.1 mrg for (e3 = 0; e3 <= 1; e3++) 835 1.1 mrg { 836 1.1 mrg int err = 0; 837 1.1 mrg unsigned int flags; 838 1.1 mrg 839 1.1 mrg flags = MPFR_FLAGS_INEXACT | 840 1.1 mrg (((rnd == MPFR_RNDU || rnd == MPFR_RNDA) 841 1.1 mrg && (i == 1 || j == 0)) || 842 1.1 mrg (rnd == MPFR_RNDN && (i == 1 && j == 0)) ? 843 1.1 mrg 0 : MPFR_FLAGS_UNDERFLOW); 844 1.1 mrg mpfr_clear_flags (); 845 1.1 mrg inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd) 846 1.1 mrg : mpfr_exp (y, x, (mpfr_rnd_t) rnd); 847 1.1 mrg if (__gmpfr_flags != flags) 848 1.1 mrg { 849 1.1 mrg printf ("Incorrect flags in underflow_up, %s", 850 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 851 1.1 mrg if (extended_emin) 852 1.1 mrg printf (" and extended emin"); 853 1.1 mrg printf ("\nfor precx = %d, precy = %d, ", 854 1.1 mrg precx, precy); 855 1.1 mrg if (j == 0) 856 1.1 mrg printf ("eps >~ -2^(-%d)", precy + i); 857 1.1 mrg else 858 1.1 mrg printf ("eps <~ - (2^(-%d) + 2^(%d))", 859 1.1 mrg precy + i, 1 - 2 * (precy + i)); 860 1.1 mrg printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp"); 861 1.1 mrg printf ("Got %u instead of %u.\n", 862 1.5 mrg (unsigned int) __gmpfr_flags, flags); 863 1.1 mrg err = 1; 864 1.1 mrg } 865 1.5 mrg if (rnd == MPFR_RNDF) 866 1.5 mrg continue; /* the test below makes no sense, since RNDF 867 1.5 mrg does not give a deterministic result */ 868 1.1 mrg if (rnd == MPFR_RNDU || rnd == MPFR_RNDA || rnd == MPFR_RNDN ? 869 1.1 mrg mpfr_cmp0 (y, minpos) != 0 : MPFR_NOTZERO (y)) 870 1.1 mrg { 871 1.1 mrg printf ("Incorrect result in underflow_up, %s", 872 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 873 1.1 mrg if (extended_emin) 874 1.1 mrg printf (" and extended emin"); 875 1.1 mrg printf ("\nfor precx = %d, precy = %d, ", 876 1.1 mrg precx, precy); 877 1.1 mrg if (j == 0) 878 1.1 mrg printf ("eps >~ -2^(-%d)", precy + i); 879 1.1 mrg else 880 1.1 mrg printf ("eps <~ - (2^(-%d) + 2^(%d))", 881 1.1 mrg precy + i, 1 - 2 * (precy + i)); 882 1.1 mrg printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp"); 883 1.1 mrg mpfr_dump (y); 884 1.1 mrg err = 1; 885 1.1 mrg } 886 1.1 mrg if (err) 887 1.1 mrg exit (1); 888 1.1 mrg } /* for (e3 ...) */ 889 1.1 mrg } /* for (j ...) */ 890 1.1 mrg mpfr_div_2si (t, t, 1, MPFR_RNDN); 891 1.1 mrg mpfr_div_2si (t2, t2, 2, MPFR_RNDN); 892 1.1 mrg } /* for (i ...) */ 893 1.1 mrg mpfr_clears (x, y, (mpfr_ptr) 0); 894 1.1 mrg } /* for (precy ...) */ 895 1.1 mrg mpfr_clears (t, t2, (mpfr_ptr) 0); 896 1.1 mrg 897 1.1 mrg /* Case exp(eps) ~= 1/2, i.e. eps ~= - log(2). 898 1.1 mrg * We choose x0 and x1 with high enough precision such that: 899 1.1 mrg * x0 = rndd(rndd(log(minpos)) - rndu(log(2))) 900 1.1 mrg * x1 = rndu(rndu(log(minpos)) - rndd(log(2))) 901 1.1 mrg * In revision 5507 (trunk) on a 64-bit Linux machine, this fails: 902 1.1 mrg * Error in underflow_up, eps >~ - log(2) and extended emin 903 1.1 mrg * for precy = 16, mpfr_exp 904 1.1 mrg * Expected 1.0@-1152921504606846976 (minimum positive MPFR number), 905 1.1 mrg * inex > 0 and flags = 9 906 1.1 mrg * Got 0 907 1.1 mrg * with inex = -1 and flags = 9 908 1.1 mrg * due to a double-rounding problem in mpfr_mul_2si when rescaling 909 1.1 mrg * the result. 910 1.1 mrg */ 911 1.1 mrg mpfr_inits2 (sizeof(mpfr_exp_t) * CHAR_BIT + 64, x, t, (mpfr_ptr) 0); 912 1.1 mrg for (i = 0; i <= 1; i++) 913 1.1 mrg { 914 1.1 mrg mpfr_log (x, minpos, i ? MPFR_RNDU : MPFR_RNDD); 915 1.1 mrg mpfr_const_log2 (t, i ? MPFR_RNDD : MPFR_RNDU); 916 1.1 mrg mpfr_sub (x, x, t, i ? MPFR_RNDU : MPFR_RNDD); 917 1.1 mrg for (precy = 16; precy <= 128; precy += 16) 918 1.1 mrg { 919 1.1 mrg mpfr_init2 (y, precy); 920 1.1 mrg for (e3 = 0; e3 <= 1; e3++) 921 1.1 mrg { 922 1.1 mrg unsigned int flags, uflags = 923 1.1 mrg MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW; 924 1.1 mrg 925 1.1 mrg mpfr_clear_flags (); 926 1.1 mrg inex = e3 ? exp_3 (y, x, MPFR_RNDN) : mpfr_exp (y, x, MPFR_RNDN); 927 1.1 mrg flags = __gmpfr_flags; 928 1.1 mrg if (flags != uflags || 929 1.1 mrg (i ? (inex <= 0 || mpfr_cmp0 (y, minpos) != 0) 930 1.1 mrg : (inex >= 0 || MPFR_NOTZERO (y)))) 931 1.1 mrg { 932 1.1 mrg printf ("Error in underflow_up, eps %c~ - log(2)", 933 1.1 mrg i ? '>' : '<'); 934 1.1 mrg if (extended_emin) 935 1.1 mrg printf (" and extended emin"); 936 1.1 mrg printf ("\nfor precy = %d, %s\nExpected ", precy, 937 1.1 mrg e3 ? "mpfr_exp_3" : "mpfr_exp"); 938 1.1 mrg if (i) 939 1.1 mrg { 940 1.1 mrg mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN); 941 1.1 mrg printf (" (minimum positive MPFR number),\ninex >"); 942 1.1 mrg } 943 1.1 mrg else 944 1.1 mrg { 945 1.1 mrg printf ("+0, inex <"); 946 1.1 mrg } 947 1.1 mrg printf (" 0 and flags = %u\nGot ", uflags); 948 1.1 mrg mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); 949 1.1 mrg printf ("\nwith inex = %d and flags = %u\n", inex, flags); 950 1.1 mrg exit (1); 951 1.1 mrg } 952 1.1 mrg } 953 1.1 mrg mpfr_clear (y); 954 1.1 mrg } 955 1.1 mrg } 956 1.1 mrg mpfr_clears (x, t, (mpfr_ptr) 0); 957 1.1 mrg 958 1.1 mrg mpfr_clear (minpos); 959 1.1 mrg } 960 1.1 mrg 961 1.1 mrg static void 962 1.1 mrg underflow (void) 963 1.1 mrg { 964 1.1 mrg mpfr_exp_t emin; 965 1.1 mrg 966 1.1 mrg underflow_up (0); 967 1.1 mrg 968 1.1 mrg emin = mpfr_get_emin (); 969 1.1 mrg set_emin (MPFR_EMIN_MIN); 970 1.1 mrg if (mpfr_get_emin () != emin) 971 1.1 mrg { 972 1.1 mrg underflow_up (1); 973 1.1 mrg set_emin (emin); 974 1.1 mrg } 975 1.1 mrg } 976 1.1 mrg 977 1.5 mrg /* bug found with GMP_CHECK_RANDOMIZE=1514290185 */ 978 1.5 mrg static void 979 1.5 mrg bug20171223 (void) 980 1.5 mrg { 981 1.5 mrg mpfr_t x, y; 982 1.5 mrg int inex; 983 1.5 mrg 984 1.5 mrg mpfr_init2 (x, 372); 985 1.5 mrg mpfr_init2 (y, 2); 986 1.5 mrg mpfr_set_str (x, "-6.9314716128384587678466323621915206417385796077947874471662159283492445979241549847386366371775938082803907383582e-01", 10, MPFR_RNDN); 987 1.5 mrg /* exp(x) = 0.500000009638..., should be rounded to 0.5 */ 988 1.5 mrg inex = mpfr_exp (y, x, MPFR_RNDD); 989 1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (y, 1, -1) == 0); 990 1.5 mrg MPFR_ASSERTN(inex < 0); 991 1.5 mrg mpfr_clear (x); 992 1.5 mrg mpfr_clear (y); 993 1.5 mrg } 994 1.5 mrg 995 1.1 mrg int 996 1.1 mrg main (int argc, char *argv[]) 997 1.1 mrg { 998 1.1 mrg tests_start_mpfr (); 999 1.1 mrg 1000 1.1 mrg if (argc > 1) 1001 1.1 mrg check_large (); 1002 1.1 mrg 1003 1.5 mrg bug20171223 (); 1004 1.5 mrg 1005 1.1 mrg check_inexact (); 1006 1.1 mrg check_special (); 1007 1.1 mrg 1008 1.5 mrg test_generic (MPFR_PREC_MIN, 100, 100); 1009 1.1 mrg 1010 1.1 mrg compare_exp2_exp3 (20, 1000); 1011 1.1 mrg check_worst_cases(); 1012 1.1 mrg check3("0.0", MPFR_RNDU, "1.0"); 1013 1.1 mrg check3("-1e-170", MPFR_RNDU, "1.0"); 1014 1.1 mrg check3("-1e-170", MPFR_RNDN, "1.0"); 1015 1.1 mrg check3("-8.88024741073346941839e-17", MPFR_RNDU, "1.0"); 1016 1.1 mrg check3("8.70772839244701057915e-01", MPFR_RNDN, "2.38875626491680437269"); 1017 1.1 mrg check3("1.0", MPFR_RNDN, "2.71828182845904509080"); 1018 1.1 mrg check3("-3.42135637628104173534e-07", MPFR_RNDZ, "0.999999657864420798958"); 1019 1.1 mrg /* worst case for argument reduction, very near from 5*log(2), 1020 1.1 mrg thanks to Jean-Michel Muller */ 1021 1.1 mrg check3("3.4657359027997265421", MPFR_RNDN, "32.0"); 1022 1.1 mrg check3("3.4657359027997265421", MPFR_RNDU, "32.0"); 1023 1.1 mrg check3("3.4657359027997265421", MPFR_RNDD, "31.999999999999996447"); 1024 1.1 mrg check3("2.26523754332090625496e+01", MPFR_RNDD, "6.8833785261699581146e9"); 1025 1.1 mrg check3("1.31478962104089092122e+01", MPFR_RNDZ, "5.12930793917860137299e+05"); 1026 1.1 mrg check3("4.25637507920002378103e-01", MPFR_RNDU, "1.53056585656161181497e+00"); 1027 1.1 mrg check3("6.26551618962329307459e-16", MPFR_RNDU, "1.00000000000000066613e+00"); 1028 1.1 mrg check3("-3.35589513871216568383e-03",MPFR_RNDD, "9.96649729583626853291e-01"); 1029 1.1 mrg check3("1.95151388850007272424e+01", MPFR_RNDU, "2.98756340674767792225e+08"); 1030 1.1 mrg check3("2.45045953503350730784e+01", MPFR_RNDN, "4.38743344916128387451e+10"); 1031 1.1 mrg check3("2.58165606081678085104e+01", MPFR_RNDD, "1.62925781879432281494e+11"); 1032 1.1 mrg check3("-2.36539020084338638128e+01",MPFR_RNDZ, "5.33630792749924762447e-11"); 1033 1.1 mrg check3("2.39211946135858077866e+01", MPFR_RNDU, "2.44817704330214385986e+10"); 1034 1.1 mrg check3("-2.78190533055889162029e+01",MPFR_RNDZ, "8.2858803483596879512e-13"); 1035 1.1 mrg check3("2.64028186174889789584e+01", MPFR_RNDD, "2.9281844652878973388e11"); 1036 1.1 mrg check3("2.92086338843268329413e+01", MPFR_RNDZ, "4.8433797301907177734e12"); 1037 1.1 mrg check3("-2.46355324071459982349e+01",MPFR_RNDZ, "1.9995129297760994791e-11"); 1038 1.1 mrg check3("-2.23509444608605427618e+01",MPFR_RNDZ, "1.9638492867489702307e-10"); 1039 1.1 mrg check3("-2.41175390197331687148e+01",MPFR_RNDD, "3.3564940885530624592e-11"); 1040 1.1 mrg check3("2.46363885231578088053e+01", MPFR_RNDU, "5.0055014282693267822e10"); 1041 1.1 mrg check3("111.1263531080090984914932050742208957672119140625", MPFR_RNDN, "1.8262572323517295459e48"); 1042 1.1 mrg check3("-3.56196340354684821250e+02",MPFR_RNDN, "2.0225297096141478156e-155"); 1043 1.1 mrg check3("6.59678273772710895173e+02", MPFR_RNDU, "3.1234469273830195529e286"); 1044 1.1 mrg check3("5.13772529701934331570e+02", MPFR_RNDD, "1.3445427121297197752e223"); 1045 1.1 mrg check3("3.57430211008718345056e+02", MPFR_RNDD, "1.6981197246857298443e155"); 1046 1.1 mrg check3("3.82001814471465536371e+02", MPFR_RNDU, "7.9667300591087367805e165"); 1047 1.1 mrg check3("5.92396038219384422518e+02", MPFR_RNDD, "1.880747529554661989e257"); 1048 1.1 mrg check3("-5.02678550462488090034e+02",MPFR_RNDU, "4.8919201895446217839e-219"); 1049 1.1 mrg check3("5.30015757134837031117e+02", MPFR_RNDD, "1.5237672861171573939e230"); 1050 1.1 mrg check3("5.16239362447650933063e+02", MPFR_RNDZ, "1.5845518406744492105e224"); 1051 1.1 mrg check3("6.00812634798592370977e-01", MPFR_RNDN, "1.823600119339019443"); 1052 1.1 mrg check_exp10 (); 1053 1.1 mrg 1054 1.1 mrg bug20080731 (); 1055 1.1 mrg 1056 1.1 mrg overflowed_exp0 (); 1057 1.1 mrg underflow (); 1058 1.1 mrg 1059 1.1 mrg data_check ("data/exp", mpfr_exp, "mpfr_exp"); 1060 1.1 mrg bad_cases (mpfr_exp, mpfr_log, "mpfr_exp", 0, -256, 255, 4, 128, 800, 50); 1061 1.1 mrg 1062 1.1 mrg tests_end_mpfr (); 1063 1.1 mrg return 0; 1064 1.1 mrg } 1065