1 /* Test file for exceptions. 2 3 Copyright 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 #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_nanflag (); 286 MPFR_ASSERTN ((mpfr_nanflag_p) ()); 287 mpfr_set_inexflag (); 288 MPFR_ASSERTN ((mpfr_inexflag_p) ()); 289 mpfr_set_erangeflag (); 290 MPFR_ASSERTN ((mpfr_erangeflag_p) ()); 291 292 mpfr_clear_flags (); 293 } 294 295 int 296 main (int argc, char *argv[]) 297 { 298 mpfr_t x, y; 299 mpfr_exp_t emin, emax; 300 301 tests_start_mpfr (); 302 303 test_set_underflow (); 304 test_set_overflow (); 305 check_default_rnd(); 306 307 mpfr_init (x); 308 mpfr_init (y); 309 310 emin = mpfr_get_emin (); 311 emax = mpfr_get_emax (); 312 if (emin >= emax) 313 { 314 printf ("Error: emin >= emax\n"); 315 exit (1); 316 } 317 318 mpfr_set_ui (x, 1, MPFR_RNDN); 319 mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); 320 mpfr_set_double_range (); 321 mpfr_check_range (x, 0, MPFR_RNDN); 322 if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0)) 323 { 324 printf ("Error: 2^1024 rounded to nearest should give +Inf\n"); 325 exit (1); 326 } 327 328 set_emax (1025); 329 mpfr_set_ui (x, 1, MPFR_RNDN); 330 mpfr_mul_2exp (x, x, 1024, MPFR_RNDN); 331 mpfr_set_double_range (); 332 mpfr_check_range (x, 0, MPFR_RNDD); 333 if (!mpfr_number_p (x)) 334 { 335 printf ("Error: 2^1024 rounded down should give a normal number\n"); 336 exit (1); 337 } 338 339 mpfr_set_ui (x, 1, MPFR_RNDN); 340 mpfr_mul_2exp (x, x, 1023, MPFR_RNDN); 341 mpfr_add (x, x, x, MPFR_RNDN); 342 if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0)) 343 { 344 printf ("Error: x+x rounded to nearest for x=2^1023 should give +Inf\n"); 345 printf ("emax = %ld\n", mpfr_get_emax ()); 346 printf ("got "); mpfr_print_binary (x); puts (""); 347 exit (1); 348 } 349 350 mpfr_set_ui (x, 1, MPFR_RNDN); 351 mpfr_mul_2exp (x, x, 1023, MPFR_RNDN); 352 mpfr_add (x, x, x, MPFR_RNDD); 353 if (!mpfr_number_p (x)) 354 { 355 printf ("Error: x+x rounded down for x=2^1023 should give" 356 " a normal number\n"); 357 exit (1); 358 } 359 360 mpfr_set_ui (x, 1, MPFR_RNDN); 361 mpfr_div_2exp (x, x, 1022, MPFR_RNDN); 362 mpfr_set_str_binary (y, "1.1e-1022"); /* y = 3/2*x */ 363 mpfr_sub (y, y, x, MPFR_RNDZ); 364 if (mpfr_cmp_ui (y, 0)) 365 { 366 printf ("Error: y-x rounded to zero should give 0" 367 " for y=3/2*2^(-1022), x=2^(-1022)\n"); 368 printf ("y="); mpfr_print_binary (y); puts (""); 369 exit (1); 370 } 371 372 set_emin (-1026); 373 mpfr_set_ui (x, 1, MPFR_RNDN); 374 mpfr_div_2exp (x, x, 1025, MPFR_RNDN); 375 mpfr_set_double_range (); 376 mpfr_check_range (x, 0, MPFR_RNDN); 377 if (!MPFR_IS_ZERO (x) ) 378 { 379 printf ("Error: x rounded to nearest for x=2^-1024 should give Zero\n"); 380 printf ("emin = %ld\n", mpfr_get_emin ()); 381 printf ("got "); mpfr_dump (x); 382 exit (1); 383 } 384 385 mpfr_clear (x); 386 mpfr_clear (y); 387 388 set_emin (emin); 389 set_emax (emax); 390 391 check_emin_emax(); 392 check_flags(); 393 check_set_get_prec (); 394 check_powerof2 (); 395 check_set (); 396 397 tests_end_mpfr (); 398 return 0; 399 } 400