1 /* Test file for mpfr_exp2. 2 3 Copyright 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. 4 Contributed by the AriC and Caramel 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 #include <limits.h> 26 27 #include "mpfr-test.h" 28 29 #define TEST_FUNCTION mpfr_exp2 30 #define TEST_RANDOM_EMIN -36 31 #define TEST_RANDOM_EMAX 36 32 #include "tgeneric.c" 33 34 static void 35 special_overflow (void) 36 { 37 mpfr_t x, y; 38 int inex; 39 mpfr_exp_t emin, emax; 40 41 emin = mpfr_get_emin (); 42 emax = mpfr_get_emax (); 43 44 set_emin (-125); 45 set_emax (128); 46 47 mpfr_init2 (x, 24); 48 mpfr_init2 (y, 24); 49 50 mpfr_set_str_binary (x, "0.101100100000000000110100E15"); 51 inex = mpfr_exp2 (y, x, MPFR_RNDN); 52 if (!mpfr_inf_p (y) || inex <= 0) 53 { 54 printf ("Overflow error.\n"); 55 mpfr_dump (y); 56 printf ("inex = %d\n", inex); 57 exit (1); 58 } 59 60 mpfr_clear (y); 61 mpfr_clear (x); 62 set_emin (emin); 63 set_emax (emax); 64 } 65 66 static void 67 emax_m_eps (void) 68 { 69 if (mpfr_get_emax () <= LONG_MAX) 70 { 71 mpfr_t x, y; 72 int inex, ov; 73 74 mpfr_init2 (x, sizeof(mpfr_exp_t) * CHAR_BIT * 4); 75 mpfr_init2 (y, 8); 76 mpfr_set_si (x, mpfr_get_emax (), MPFR_RNDN); 77 78 mpfr_clear_flags (); 79 inex = mpfr_exp2 (y, x, MPFR_RNDN); 80 ov = mpfr_overflow_p (); 81 if (!ov || !mpfr_inf_p (y) || inex <= 0) 82 { 83 printf ("Overflow error for x = emax, MPFR_RNDN.\n"); 84 mpfr_dump (y); 85 printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no "); 86 exit (1); 87 } 88 89 mpfr_nextbelow (x); 90 91 mpfr_clear_flags (); 92 inex = mpfr_exp2 (y, x, MPFR_RNDN); 93 ov = mpfr_overflow_p (); 94 if (!ov || !mpfr_inf_p (y) || inex <= 0) 95 { 96 printf ("Overflow error for x = emax - eps, MPFR_RNDN.\n"); 97 mpfr_dump (y); 98 printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no "); 99 exit (1); 100 } 101 102 mpfr_clear_flags (); 103 inex = mpfr_exp2 (y, x, MPFR_RNDD); 104 ov = mpfr_overflow_p (); 105 if (ov || mpfr_inf_p (y) || inex >= 0 || 106 (mpfr_nextabove (y), !mpfr_inf_p (y))) 107 { 108 printf ("Overflow error for x = emax - eps, MPFR_RNDD.\n"); 109 mpfr_dump (y); 110 printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no "); 111 exit (1); 112 } 113 114 mpfr_clear (x); 115 mpfr_clear (y); 116 } 117 } 118 119 static void 120 exp_range (void) 121 { 122 mpfr_t x; 123 mpfr_exp_t emin; 124 125 emin = mpfr_get_emin (); 126 set_emin (3); 127 mpfr_init2 (x, 8); 128 mpfr_set_ui (x, 5, MPFR_RNDN); 129 mpfr_exp2 (x, x, MPFR_RNDN); 130 set_emin (emin); 131 if (mpfr_nan_p (x) || mpfr_cmp_ui (x, 32) != 0) 132 { 133 printf ("Error in mpfr_exp2 for x = 5, with emin = 3\n"); 134 printf ("Expected 32, got "); 135 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); 136 printf ("\n"); 137 exit (1); 138 } 139 mpfr_clear (x); 140 } 141 142 static void 143 overflowed_exp2_0 (void) 144 { 145 mpfr_t x, y; 146 int emax, i, inex, rnd, err = 0; 147 mpfr_exp_t old_emax; 148 149 old_emax = mpfr_get_emax (); 150 151 mpfr_init2 (x, 8); 152 mpfr_init2 (y, 8); 153 154 for (emax = -1; emax <= 0; emax++) 155 { 156 mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN); 157 mpfr_nextbelow (y); 158 set_emax (emax); /* 1 is not representable. */ 159 /* and if emax < 0, 1 - eps is not representable either. */ 160 for (i = -1; i <= 1; i++) 161 RND_LOOP (rnd) 162 { 163 mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN); 164 mpfr_clear_flags (); 165 inex = mpfr_exp2 (x, x, (mpfr_rnd_t) rnd); 166 if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) && 167 ! mpfr_overflow_p ()) 168 { 169 printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n" 170 " The overflow flag is not set.\n", 171 i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 172 err = 1; 173 } 174 if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) 175 { 176 if (inex >= 0) 177 { 178 printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n" 179 " The inexact value must be negative.\n", 180 i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 181 err = 1; 182 } 183 if (! mpfr_equal_p (x, y)) 184 { 185 printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n" 186 " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 187 mpfr_print_binary (x); 188 printf (" instead of 0.11111111E%d.\n", emax); 189 err = 1; 190 } 191 } 192 else 193 { 194 if (inex <= 0) 195 { 196 printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n" 197 " The inexact value must be positive.\n", 198 i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 199 err = 1; 200 } 201 if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0)) 202 { 203 printf ("Error in overflowed_exp2_0 (i = %d, rnd = %s):\n" 204 " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 205 mpfr_print_binary (x); 206 printf (" instead of +Inf.\n"); 207 err = 1; 208 } 209 } 210 } 211 set_emax (old_emax); 212 } 213 214 if (err) 215 exit (1); 216 mpfr_clear (x); 217 mpfr_clear (y); 218 } 219 220 int 221 main (int argc, char *argv[]) 222 { 223 mpfr_t x, y; 224 mpfr_exp_t emin, emax; 225 226 tests_start_mpfr (); 227 228 special_overflow (); 229 emax_m_eps (); 230 exp_range (); 231 232 mpfr_init (x); 233 mpfr_init (y); 234 235 mpfr_set_ui (x, 4, MPFR_RNDN); 236 mpfr_exp2 (y, x, MPFR_RNDN); 237 if (mpfr_cmp_ui (y, 16) != 0) 238 { 239 printf ("Error for 2^4, MPFR_RNDN\n"); 240 exit (1); 241 } 242 mpfr_exp2 (y, x, MPFR_RNDD); 243 if (mpfr_cmp_ui (y, 16) != 0) 244 { 245 printf ("Error for 2^4, MPFR_RNDD\n"); 246 exit (1); 247 } 248 mpfr_exp2 (y, x, MPFR_RNDU); 249 if (mpfr_cmp_ui (y, 16) != 0) 250 { 251 printf ("Error for 2^4, MPFR_RNDU\n"); 252 exit (1); 253 } 254 255 mpfr_set_si (x, -4, MPFR_RNDN); 256 mpfr_exp2 (y, x, MPFR_RNDN); 257 if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) 258 { 259 printf ("Error for 2^(-4), MPFR_RNDN\n"); 260 exit (1); 261 } 262 mpfr_exp2 (y, x, MPFR_RNDD); 263 if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) 264 { 265 printf ("Error for 2^(-4), MPFR_RNDD\n"); 266 exit (1); 267 } 268 mpfr_exp2 (y, x, MPFR_RNDU); 269 if (mpfr_cmp_ui_2exp (y, 1, -4) != 0) 270 { 271 printf ("Error for 2^(-4), MPFR_RNDU\n"); 272 exit (1); 273 } 274 275 mpfr_set_prec (x, 53); 276 mpfr_set_prec (y, 53); 277 mpfr_set_str (x, /*-1683977482443233.0 / 2199023255552.0*/ 278 "-7.6578429909351734750089235603809357e2", 10, MPFR_RNDN); 279 mpfr_exp2 (y, x, MPFR_RNDN); 280 if (mpfr_cmp_str1 (y, "2.991959870867646566478e-231")) 281 { 282 printf ("Error for x=-1683977482443233/2^41\n"); 283 exit (1); 284 } 285 286 mpfr_set_prec (x, 10); 287 mpfr_set_prec (y, 10); 288 /* save emin */ 289 emin = mpfr_get_emin (); 290 set_emin (-10); 291 mpfr_set_si (x, -12, MPFR_RNDN); 292 mpfr_exp2 (y, x, MPFR_RNDN); 293 if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) 294 { 295 printf ("Error for x=emin-2, RNDN\n"); 296 printf ("Expected +0\n"); 297 printf ("Got "); mpfr_print_binary (y); puts (""); 298 exit (1); 299 } 300 /* restore emin */ 301 set_emin (emin); 302 303 /* save emax */ 304 emax = mpfr_get_emax (); 305 set_emax (10); 306 mpfr_set_ui (x, 11, MPFR_RNDN); 307 mpfr_exp2 (y, x, MPFR_RNDN); 308 if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) 309 { 310 printf ("Error for x=emax+1, RNDN\n"); 311 exit (1); 312 } 313 /* restore emax */ 314 set_emax (emax); 315 316 MPFR_SET_INF(x); 317 MPFR_SET_POS(x); 318 mpfr_exp2 (y, x, MPFR_RNDN); 319 if(!MPFR_IS_INF(y)) 320 { 321 printf ("evaluation of function in INF does not return INF\n"); 322 exit (1); 323 } 324 325 MPFR_CHANGE_SIGN(x); 326 mpfr_exp2 (y, x, MPFR_RNDN); 327 if(!MPFR_IS_ZERO(y)) 328 { 329 printf ("evaluation of function in -INF does not return 0\n"); 330 exit (1); 331 } 332 333 MPFR_SET_NAN(x); 334 mpfr_exp2 (y, x, MPFR_RNDN); 335 if(!MPFR_IS_NAN(y)) 336 { 337 printf ("evaluation of function in NaN does not return NaN\n"); 338 exit (1); 339 } 340 341 if ((mpfr_uexp_t) 8 << 31 != 0 || 342 mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000) 343 { 344 /* emax <= 10000000000 */ 345 mpfr_set_prec (x, 40); 346 mpfr_set_prec (y, 40); 347 mpfr_set_str (x, "10000000000.5", 10, MPFR_RNDN); 348 mpfr_clear_flags (); 349 mpfr_exp2 (y, x, MPFR_RNDN); 350 if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && mpfr_overflow_p ())) 351 { 352 printf ("exp2(10000000000.5) should overflow.\n"); 353 exit (1); 354 } 355 } 356 357 mpfr_set_prec (x, 2); 358 mpfr_set_prec (y, 2); 359 mpfr_set_str_binary (x, "-1.0E-26"); 360 mpfr_exp2 (y, x, MPFR_RNDD); 361 mpfr_set_str_binary (x, "1.1E-1"); 362 if (mpfr_cmp (x, y)) 363 { 364 printf ("Error for exp(-2^(-26)) for prec=2\n"); 365 exit (1); 366 } 367 368 test_generic (2, 100, 100); 369 370 mpfr_clear (x); 371 mpfr_clear (y); 372 373 overflowed_exp2_0 (); 374 375 data_check ("data/exp2", mpfr_exp2, "mpfr_exp2"); 376 377 tests_end_mpfr (); 378 return 0; 379 } 380