1 /* Test file for exceptions. 2 3 Copyright 2001-2016 Free Software Foundation, Inc. 4 Contributed by the AriC and Caramba 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 #define ERROR(s) do { printf(s"\n"); exit(1); } while(0) 29 30 /* Test powerof2 */ 31 static void 32 check_powerof2 (void) 33 { 34 mpfr_t x; 35 36 mpfr_init (x); 37 mpfr_set_ui (x, 1, MPFR_RNDN); 38 MPFR_ASSERTN (mpfr_powerof2_raw (x)); 39 mpfr_set_ui (x, 3, MPFR_RNDN); 40 MPFR_ASSERTN (!mpfr_powerof2_raw (x)); 41 mpfr_clear (x); 42 } 43 44 /* Test default rounding mode */ 45 static void 46 check_default_rnd (void) 47 { 48 int r; 49 mpfr_rnd_t t; 50 for(r = 0 ; r < MPFR_RND_MAX ; r++) 51 { 52 mpfr_set_default_rounding_mode ((mpfr_rnd_t) r); 53 t = (mpfr_get_default_rounding_mode) (); 54 if ((mpfr_rnd_t) r != t) 55 { 56 printf ("%s %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r), 57 mpfr_print_rnd_mode (t)); 58 ERROR("ERROR in setting / getting default rounding mode (1)"); 59 } 60 } 61 mpfr_set_default_rounding_mode ((mpfr_rnd_t) MPFR_RND_MAX); 62 if (mpfr_get_default_rounding_mode() != MPFR_RNDA) 63 ERROR("ERROR in setting / getting default rounding mode (2)"); 64 mpfr_set_default_rounding_mode((mpfr_rnd_t) -1); 65 if (mpfr_get_default_rounding_mode() != MPFR_RNDA) 66 ERROR("ERROR in setting / getting default rounding mode (3)"); 67 } 68 69 static void 70 check_emin_emax (void) 71 { 72 mpfr_exp_t old_emin, old_emax; 73 74 old_emin = mpfr_get_emin (); 75 old_emax = mpfr_get_emax (); 76 77 /* Check the functions not the macros ! */ 78 if ((mpfr_set_emin)(MPFR_EMIN_MIN) != 0) 79 ERROR("set_emin failed!"); 80 if ((mpfr_get_emin)() != MPFR_EMIN_MIN) 81 ERROR("get_emin FAILED!"); 82 if ((mpfr_set_emin)(MPFR_EMIN_MIN-1) == 0) 83 ERROR("set_emin failed! (2)"); 84 85 if ((mpfr_set_emax)(MPFR_EMAX_MAX) != 0) 86 ERROR("set_emax failed!"); 87 if ((mpfr_get_emax)() != MPFR_EMAX_MAX) 88 ERROR("get_emax FAILED!"); 89 if ((mpfr_set_emax)(MPFR_EMAX_MAX+1) == 0) 90 ERROR("set_emax failed! (2)"); 91 92 if ((mpfr_get_emin_min) () != MPFR_EMIN_MIN) 93 ERROR ("get_emin_min"); 94 if ((mpfr_get_emin_max) () != MPFR_EMIN_MAX) 95 ERROR ("get_emin_max"); 96 if ((mpfr_get_emax_min) () != MPFR_EMAX_MIN) 97 ERROR ("get_emax_min"); 98 if ((mpfr_get_emax_max) () != MPFR_EMAX_MAX) 99 ERROR ("get_emax_max"); 100 101 set_emin (old_emin); 102 set_emax (old_emax); 103 } 104 105 static void 106 check_set_get_prec (void) 107 { 108 mpfr_t x; 109 110 mpfr_init2 (x, 17); 111 if (mpfr_get_prec (x) != 17 || (mpfr_get_prec)(x) != 17) 112 ERROR ("mpfr_get_prec"); 113 mpfr_clear (x); 114 } 115 116 static void 117 mpfr_set_double_range (void) 118 { 119 mpfr_set_default_prec (54); 120 if (mpfr_get_default_prec () != 54) 121 ERROR ("get_default_prec failed (1)"); 122 mpfr_set_default_prec (53); 123 if ((mpfr_get_default_prec) () != 53) 124 ERROR ("get_default_prec failed (2)"); 125 126 /* in double precision format, the unbiased exponent is between 0 and 127 2047, where 0 is used for subnormal numbers, and 2047 for special 128 numbers (infinities, NaN), and the bias is 1023, thus "normal" numbers 129 have an exponent between -1022 and 1023, corresponding to numbers 130 between 2^(-1022) and previous(2^(1024)). 131 (The smallest subnormal number is 0.(0^51)1*2^(-1022)= 2^(-1074).) 132 133 The smallest normal power of two is 1.0*2^(-1022). 134 The largest normal power of two is 2^1023. 135 (We have to add one for mpfr since mantissa are between 1/2 and 1.) 136 */ 137 138 set_emin (-1021); 139 set_emax (1024); 140 } 141 142 static void 143 check_flags (void) 144 { 145 mpfr_t x; 146 mpfr_exp_t old_emin, old_emax; 147 148 old_emin = mpfr_get_emin (); 149 old_emax = mpfr_get_emax (); 150 mpfr_init (x); 151 152 /* Check the functions not the macros ! */ 153 (mpfr_clear_flags)(); 154 mpfr_set_double_range (); 155 156 mpfr_set_ui (x, 1, MPFR_RNDN); 157 (mpfr_clear_overflow)(); 158 mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); 159 if (!(mpfr_overflow_p)()) 160 ERROR("ERROR: No overflow detected!\n"); 161 162 (mpfr_clear_underflow)(); 163 mpfr_set_ui (x, 1, MPFR_RNDN); 164 mpfr_div_2exp (x, x, 1025, MPFR_RNDN); 165 if (!(mpfr_underflow_p)()) 166 ERROR("ERROR: No underflow detected!\n"); 167 168 (mpfr_clear_nanflag)(); 169 MPFR_SET_NAN(x); 170 mpfr_add (x, x, x, MPFR_RNDN); 171 if (!(mpfr_nanflag_p)()) 172 ERROR("ERROR: No NaN flag!\n"); 173 174 (mpfr_clear_inexflag)(); 175 mpfr_set_ui(x, 2, MPFR_RNDN); 176 mpfr_cos(x, x, MPFR_RNDN); 177 if (!(mpfr_inexflag_p)()) 178 ERROR("ERROR: No inexact flag!\n"); 179 180 (mpfr_clear_erangeflag) (); 181 mpfr_set_ui (x, 1, MPFR_RNDN); 182 mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); 183 mpfr_get_ui (x, MPFR_RNDN); 184 if (!(mpfr_erangeflag_p)()) 185 ERROR ("ERROR: No erange flag!\n"); 186 187 mpfr_clear (x); 188 set_emin (old_emin); 189 set_emax (old_emax); 190 } 191 192 static void 193 test_set_underflow (void) 194 { 195 mpfr_t x, zero, min; 196 mpfr_ptr r[MPFR_RND_MAX]; 197 int t[MPFR_RND_MAX] = { 1, -1, 1, -1, 1 }; /* RNDN, RNDZ, RNDU, RNDD, RNDA */ 198 int i; 199 int s; 200 201 mpfr_inits (x, zero, min, (mpfr_ptr) 0); 202 mpfr_set_ui (zero, 0, MPFR_RNDN); 203 mpfr_set_ui (min, 0, MPFR_RNDN); 204 mpfr_nextabove (min); 205 r[0] = r[2] = r[4] = min; /* RNDN, RNDU, RNDA */ 206 r[1] = r[3] = zero; /* RNDZ, RNDD */ 207 for (s = 1; s > 0; s = -1) 208 { 209 for (i = 0; i < MPFR_RND_MAX ; i++) 210 { 211 int j; 212 int inex; 213 214 j = s < 0 && i > 1 ? 5 - i : i; 215 inex = mpfr_underflow (x, (mpfr_rnd_t) i, s); 216 if (mpfr_cmp (x, r[j]) || inex * t[j] <= 0) 217 { 218 printf ("Error in test_set_underflow, sign = %d," 219 " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i)); 220 printf ("Got\n"); 221 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); 222 printf (", inex = %d\ninstead of\n", inex); 223 mpfr_out_str (stdout, 2, 0, r[j], MPFR_RNDN); 224 printf (", inex = %d\n", t[j]); 225 exit (1); 226 } 227 } 228 mpfr_neg (zero, zero, MPFR_RNDN); 229 mpfr_neg (min, min, MPFR_RNDN); 230 } 231 mpfr_clears (x, zero, min, (mpfr_ptr) 0); 232 } 233 234 static void 235 test_set_overflow (void) 236 { 237 mpfr_t x, inf, max; 238 mpfr_ptr r[MPFR_RND_MAX]; 239 int t[MPFR_RND_MAX] = { 1, -1, 1, -1, 1 }; /* RNDN, RNDZ, RNDU, RNDD, RNDA */ 240 int i; 241 int s; 242 243 mpfr_inits2 (32, x, inf, max, (mpfr_ptr) 0); 244 mpfr_set_inf (inf, 1); 245 mpfr_set_inf (max, 1); 246 mpfr_nextbelow (max); 247 r[0] = r[2] = r[4] = inf; /* RNDN, RNDU, RNDA */ 248 r[1] = r[3] = max; /* RNDZ, RNDD */ 249 for (s = 1; s > 0; s = -1) 250 { 251 for (i = 0; i < MPFR_RND_MAX ; i++) 252 { 253 int j; 254 int inex; 255 256 j = s < 0 && i > 1 ? 5 - i : i; 257 inex = mpfr_overflow (x, (mpfr_rnd_t) i, s); 258 if (mpfr_cmp (x, r[j]) || inex * t[j] <= 0) 259 { 260 printf ("Error in test_set_overflow, sign = %d," 261 " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i)); 262 printf ("Got\n"); 263 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); 264 printf (", inex = %d\ninstead of\n", inex); 265 mpfr_out_str (stdout, 2, 0, r[j], MPFR_RNDN); 266 printf (", inex = %d\n", t[j]); 267 exit (1); 268 } 269 } 270 mpfr_neg (inf, inf, MPFR_RNDN); 271 mpfr_neg (max, max, MPFR_RNDN); 272 } 273 mpfr_clears (x, inf, max, (mpfr_ptr) 0); 274 } 275 276 static void 277 check_set (void) 278 { 279 mpfr_clear_flags (); 280 281 mpfr_set_overflow (); 282 MPFR_ASSERTN ((mpfr_overflow_p) ()); 283 mpfr_set_underflow (); 284 MPFR_ASSERTN ((mpfr_underflow_p) ()); 285 mpfr_set_divby0 (); 286 MPFR_ASSERTN ((mpfr_divby0_p) ()); 287 mpfr_set_nanflag (); 288 MPFR_ASSERTN ((mpfr_nanflag_p) ()); 289 mpfr_set_inexflag (); 290 MPFR_ASSERTN ((mpfr_inexflag_p) ()); 291 mpfr_set_erangeflag (); 292 MPFR_ASSERTN ((mpfr_erangeflag_p) ()); 293 294 MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_ALL); 295 296 mpfr_clear_overflow (); 297 MPFR_ASSERTN (! (mpfr_overflow_p) ()); 298 mpfr_clear_underflow (); 299 MPFR_ASSERTN (! (mpfr_underflow_p) ()); 300 mpfr_clear_divby0 (); 301 MPFR_ASSERTN (! (mpfr_divby0_p) ()); 302 mpfr_clear_nanflag (); 303 MPFR_ASSERTN (! (mpfr_nanflag_p) ()); 304 mpfr_clear_inexflag (); 305 MPFR_ASSERTN (! (mpfr_inexflag_p) ()); 306 mpfr_clear_erangeflag (); 307 MPFR_ASSERTN (! (mpfr_erangeflag_p) ()); 308 309 MPFR_ASSERTN (__gmpfr_flags == 0); 310 311 (mpfr_set_overflow) (); 312 MPFR_ASSERTN (mpfr_overflow_p ()); 313 (mpfr_set_underflow) (); 314 MPFR_ASSERTN (mpfr_underflow_p ()); 315 (mpfr_set_divby0) (); 316 MPFR_ASSERTN (mpfr_divby0_p ()); 317 (mpfr_set_nanflag) (); 318 MPFR_ASSERTN (mpfr_nanflag_p ()); 319 (mpfr_set_inexflag) (); 320 MPFR_ASSERTN (mpfr_inexflag_p ()); 321 (mpfr_set_erangeflag) (); 322 MPFR_ASSERTN (mpfr_erangeflag_p ()); 323 324 MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_ALL); 325 326 (mpfr_clear_overflow) (); 327 MPFR_ASSERTN (! mpfr_overflow_p ()); 328 (mpfr_clear_underflow) (); 329 MPFR_ASSERTN (! mpfr_underflow_p ()); 330 (mpfr_clear_divby0) (); 331 MPFR_ASSERTN (! mpfr_divby0_p ()); 332 (mpfr_clear_nanflag) (); 333 MPFR_ASSERTN (! mpfr_nanflag_p ()); 334 (mpfr_clear_inexflag) (); 335 MPFR_ASSERTN (! mpfr_inexflag_p ()); 336 (mpfr_clear_erangeflag) (); 337 MPFR_ASSERTN (! mpfr_erangeflag_p ()); 338 339 MPFR_ASSERTN (__gmpfr_flags == 0); 340 } 341 342 int 343 main (int argc, char *argv[]) 344 { 345 mpfr_t x, y; 346 mpfr_exp_t emin, emax; 347 348 tests_start_mpfr (); 349 350 test_set_underflow (); 351 test_set_overflow (); 352 check_default_rnd(); 353 354 mpfr_init (x); 355 mpfr_init (y); 356 357 emin = mpfr_get_emin (); 358 emax = mpfr_get_emax (); 359 if (emin >= emax) 360 { 361 printf ("Error: emin >= emax\n"); 362 exit (1); 363 } 364 365 mpfr_set_ui (x, 1, MPFR_RNDN); 366 mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); 367 mpfr_set_double_range (); 368 mpfr_check_range (x, 0, MPFR_RNDN); 369 if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0)) 370 { 371 printf ("Error: 2^1024 rounded to nearest should give +Inf\n"); 372 exit (1); 373 } 374 375 set_emax (1025); 376 mpfr_set_ui (x, 1, MPFR_RNDN); 377 mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); 378 mpfr_set_double_range (); 379 mpfr_check_range (x, 0, MPFR_RNDD); 380 if (!mpfr_number_p (x)) 381 { 382 printf ("Error: 2^1024 rounded down should give a normal number\n"); 383 exit (1); 384 } 385 386 mpfr_set_ui (x, 1, MPFR_RNDN); 387 mpfr_mul_2exp (x, x, 1023, MPFR_RNDN); 388 mpfr_add (x, x, x, MPFR_RNDN); 389 if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0)) 390 { 391 printf ("Error: x+x rounded to nearest for x=2^1023 should give +Inf\n"); 392 printf ("emax = %ld\n", (long) mpfr_get_emax ()); 393 printf ("got "); mpfr_print_binary (x); puts (""); 394 exit (1); 395 } 396 397 mpfr_set_ui (x, 1, MPFR_RNDN); 398 mpfr_mul_2exp (x, x, 1023, MPFR_RNDN); 399 mpfr_add (x, x, x, MPFR_RNDD); 400 if (!mpfr_number_p (x)) 401 { 402 printf ("Error: x+x rounded down for x=2^1023 should give" 403 " a normal number\n"); 404 exit (1); 405 } 406 407 mpfr_set_ui (x, 1, MPFR_RNDN); 408 mpfr_div_2exp (x, x, 1022, MPFR_RNDN); 409 mpfr_set_str_binary (y, "1.1e-1022"); /* y = 3/2*x */ 410 mpfr_sub (y, y, x, MPFR_RNDZ); 411 if (mpfr_cmp_ui (y, 0)) 412 { 413 printf ("Error: y-x rounded to zero should give 0" 414 " for y=3/2*2^(-1022), x=2^(-1022)\n"); 415 printf ("y="); mpfr_print_binary (y); puts (""); 416 exit (1); 417 } 418 419 set_emin (-1026); 420 mpfr_set_ui (x, 1, MPFR_RNDN); 421 mpfr_div_2exp (x, x, 1025, MPFR_RNDN); 422 mpfr_set_double_range (); 423 mpfr_check_range (x, 0, MPFR_RNDN); 424 if (!MPFR_IS_ZERO (x) ) 425 { 426 printf ("Error: x rounded to nearest for x=2^-1024 should give Zero\n"); 427 printf ("emin = %ld\n", (long) mpfr_get_emin ()); 428 printf ("got "); mpfr_dump (x); 429 exit (1); 430 } 431 432 mpfr_clear (x); 433 mpfr_clear (y); 434 435 set_emin (emin); 436 set_emax (emax); 437 438 check_emin_emax(); 439 check_flags(); 440 check_set_get_prec (); 441 check_powerof2 (); 442 check_set (); 443 444 tests_end_mpfr (); 445 return 0; 446 } 447