1 /* Test file for mpfr_{mul,div}_2{ui,si}. 2 3 Copyright 1999, 2001, 2002, 2003, 2004, 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 static const char * const val[] = { 29 "1.0001@100","4.0004000000000@102", "4.0004000000000@97", 30 "1.ABF012345@-100","6.afc048d140000@-98","6.afc048d140000@-103", 31 "F.FFFFFFFFF@10000","3.fffffffffc000@10003","3.fffffffffc000@9998", 32 "1.23456789ABCDEF@42","4.8d159e26af37c@44","4.8d159e26af37c@39", 33 "17@42","5.c000000000000@45","5.c000000000000@40", 34 "42@-17","1.0800000000000@-13","1.0800000000000@-18" 35 }; 36 37 static int 38 test_mul (int i, int div, mpfr_ptr y, mpfr_srcptr x, 39 unsigned long int n, mpfr_rnd_t r) 40 { 41 return 42 i == 0 ? (div ? mpfr_div_2ui : mpfr_mul_2ui) (y, x, n, r) : 43 i == 1 ? (div ? mpfr_div_2si : mpfr_mul_2si) (y, x, n, r) : 44 i == 2 ? (div ? mpfr_mul_2si : mpfr_div_2si) (y, x, -n, r) : 45 (exit (1), 0); 46 } 47 48 static void 49 underflow (mpfr_exp_t e) 50 { 51 mpfr_t x, y, z1, z2; 52 mpfr_exp_t emin; 53 int i, k; 54 int prec; 55 int rnd; 56 int div; 57 int inex1, inex2; 58 unsigned int flags1, flags2; 59 60 /* Test mul_2si(x, e - k), div_2si(x, k - e) and div_2ui(x, k - e) 61 * with emin = e, x = 1 + i/16, i in { -1, 0, 1 }, and k = 1 to 4, 62 * by comparing the result with the one of a simple division. 63 */ 64 emin = mpfr_get_emin (); 65 set_emin (e); 66 mpfr_inits2 (8, x, y, (mpfr_ptr) 0); 67 for (i = 15; i <= 17; i++) 68 { 69 inex1 = mpfr_set_ui_2exp (x, i, -4, MPFR_RNDN); 70 MPFR_ASSERTN (inex1 == 0); 71 for (prec = 6; prec >= 3; prec -= 3) 72 { 73 mpfr_inits2 (prec, z1, z2, (mpfr_ptr) 0); 74 RND_LOOP (rnd) 75 for (k = 1; k <= 4; k++) 76 { 77 /* The following one is assumed to be correct. */ 78 inex1 = mpfr_mul_2si (y, x, e, MPFR_RNDN); 79 MPFR_ASSERTN (inex1 == 0); 80 inex1 = mpfr_set_ui (z1, 1 << k, MPFR_RNDN); 81 MPFR_ASSERTN (inex1 == 0); 82 mpfr_clear_flags (); 83 /* Do not use mpfr_div_ui to avoid the optimization 84 by mpfr_div_2si. */ 85 inex1 = mpfr_div (z1, y, z1, (mpfr_rnd_t) rnd); 86 flags1 = __gmpfr_flags; 87 88 for (div = 0; div <= 2; div++) 89 { 90 mpfr_clear_flags (); 91 inex2 = div == 0 ? 92 mpfr_mul_2si (z2, x, e - k, (mpfr_rnd_t) rnd) : div == 1 ? 93 mpfr_div_2si (z2, x, k - e, (mpfr_rnd_t) rnd) : 94 mpfr_div_2ui (z2, x, k - e, (mpfr_rnd_t) rnd); 95 flags2 = __gmpfr_flags; 96 if (flags1 == flags2 && SAME_SIGN (inex1, inex2) && 97 mpfr_equal_p (z1, z2)) 98 continue; 99 printf ("Error in underflow("); 100 if (e == MPFR_EMIN_MIN) 101 printf ("MPFR_EMIN_MIN"); 102 else if (e == emin) 103 printf ("default emin"); 104 else 105 printf ("%ld", e); 106 printf (") with mpfr_%s,\nx = %d/16, prec = %d, k = %d, " 107 "%s\n", div == 0 ? "mul_2si" : div == 1 ? 108 "div_2si" : "div_2ui", i, prec, k, 109 mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 110 printf ("Expected "); 111 mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN); 112 printf (", inex = %d, flags = %u\n", SIGN (inex1), flags1); 113 printf ("Got "); 114 mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN); 115 printf (", inex = %d, flags = %u\n", SIGN (inex2), flags2); 116 exit (1); 117 } /* div */ 118 } /* k */ 119 mpfr_clears (z1, z2, (mpfr_ptr) 0); 120 } /* prec */ 121 } /* i */ 122 mpfr_clears (x, y, (mpfr_ptr) 0); 123 set_emin (emin); 124 } 125 126 static void 127 underflow0 (void) 128 { 129 underflow (-256); 130 if (mpfr_get_emin () != MPFR_EMIN_MIN) 131 underflow (mpfr_get_emin ()); 132 underflow (MPFR_EMIN_MIN); 133 } 134 135 static void 136 large (mpfr_exp_t e) 137 { 138 mpfr_t x, y, z; 139 mpfr_exp_t emax; 140 int inex; 141 unsigned int flags; 142 143 emax = mpfr_get_emax (); 144 set_emax (e); 145 mpfr_init2 (x, 8); 146 mpfr_init2 (y, 8); 147 mpfr_init2 (z, 4); 148 149 mpfr_set_inf (x, 1); 150 mpfr_nextbelow (x); 151 152 mpfr_mul_2si (y, x, -1, MPFR_RNDU); 153 mpfr_prec_round (y, 4, MPFR_RNDU); 154 155 mpfr_clear_flags (); 156 inex = mpfr_mul_2si (z, x, -1, MPFR_RNDU); 157 flags = __gmpfr_flags; 158 159 if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z)) 160 { 161 printf ("Error in large("); 162 if (e == MPFR_EMAX_MAX) 163 printf ("MPFR_EMAX_MAX"); 164 else if (e == emax) 165 printf ("default emax"); 166 else if (e <= LONG_MAX) 167 printf ("%ld", (long) e); 168 else 169 printf (">LONG_MAX"); 170 printf (") for mpfr_mul_2si\n"); 171 printf ("Expected inex > 0, flags = %u,\n y = ", 172 (unsigned int) MPFR_FLAGS_INEXACT); 173 mpfr_dump (y); 174 printf ("Got inex = %d, flags = %u,\n y = ", 175 inex, flags); 176 mpfr_dump (z); 177 exit (1); 178 } 179 180 mpfr_clear_flags (); 181 inex = mpfr_div_2si (z, x, 1, MPFR_RNDU); 182 flags = __gmpfr_flags; 183 184 if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z)) 185 { 186 printf ("Error in large("); 187 if (e == MPFR_EMAX_MAX) 188 printf ("MPFR_EMAX_MAX"); 189 else if (e == emax) 190 printf ("default emax"); 191 else if (e <= LONG_MAX) 192 printf ("%ld", (long) e); 193 else 194 printf (">LONG_MAX"); 195 printf (") for mpfr_div_2si\n"); 196 printf ("Expected inex > 0, flags = %u,\n y = ", 197 (unsigned int) MPFR_FLAGS_INEXACT); 198 mpfr_dump (y); 199 printf ("Got inex = %d, flags = %u,\n y = ", 200 inex, flags); 201 mpfr_dump (z); 202 exit (1); 203 } 204 205 mpfr_clear_flags (); 206 inex = mpfr_div_2ui (z, x, 1, MPFR_RNDU); 207 flags = __gmpfr_flags; 208 209 if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z)) 210 { 211 printf ("Error in large("); 212 if (e == MPFR_EMAX_MAX) 213 printf ("MPFR_EMAX_MAX"); 214 else if (e == emax) 215 printf ("default emax"); 216 else if (e <= LONG_MAX) 217 printf ("%ld", (long) e); 218 else 219 printf (">LONG_MAX"); 220 printf (") for mpfr_div_2ui\n"); 221 printf ("Expected inex > 0, flags = %u,\n y = ", 222 (unsigned int) MPFR_FLAGS_INEXACT); 223 mpfr_dump (y); 224 printf ("Got inex = %d, flags = %u,\n y = ", 225 inex, flags); 226 mpfr_dump (z); 227 exit (1); 228 } 229 230 mpfr_clears (x, y, z, (mpfr_ptr) 0); 231 set_emax (emax); 232 } 233 234 static void 235 large0 (void) 236 { 237 large (256); 238 if (mpfr_get_emax () != MPFR_EMAX_MAX) 239 large (mpfr_get_emax ()); 240 large (MPFR_EMAX_MAX); 241 } 242 243 int 244 main (int argc, char *argv[]) 245 { 246 mpfr_t w,z; 247 unsigned long k; 248 int i; 249 250 tests_start_mpfr (); 251 252 mpfr_inits2 (53, w, z, (mpfr_ptr) 0); 253 254 for (i = 0; i < 3; i++) 255 { 256 mpfr_set_inf (w, 1); 257 test_mul (i, 0, w, w, 10, MPFR_RNDZ); 258 if (!MPFR_IS_INF(w)) 259 { 260 printf ("Result is not Inf (i = %d)\n", i); 261 exit (1); 262 } 263 264 mpfr_set_nan (w); 265 test_mul (i, 0, w, w, 10, MPFR_RNDZ); 266 if (!MPFR_IS_NAN(w)) 267 { 268 printf ("Result is not NaN (i = %d)\n", i); 269 exit (1); 270 } 271 272 for (k = 0 ; k < numberof(val) ; k+=3) 273 { 274 mpfr_set_str (w, val[k], 16, MPFR_RNDN); 275 test_mul (i, 0, z, w, 10, MPFR_RNDZ); 276 if (mpfr_cmp_str (z, val[k+1], 16, MPFR_RNDN)) 277 { 278 printf ("ERROR for x * 2^n (i = %d) for %s\n", i, val[k]); 279 printf ("Expected: %s\n" 280 "Got : ", val[k+1]); 281 mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); 282 putchar ('\n'); 283 exit (1); 284 } 285 test_mul (i, 1, z, w, 10, MPFR_RNDZ); 286 if (mpfr_cmp_str (z, val[k+2], 16, MPFR_RNDN)) 287 { 288 printf ("ERROR for x / 2^n (i = %d) for %s\n", i, val[k]); 289 printf ("Expected: %s\n" 290 "Got : ", val[k+2]); 291 mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); 292 putchar ('\n'); 293 exit (1); 294 } 295 } 296 297 mpfr_set_inf (w, 1); 298 mpfr_nextbelow (w); 299 test_mul (i, 0, w, w, 1, MPFR_RNDN); 300 if (!mpfr_inf_p (w)) 301 { 302 printf ("Overflow error (i = %d)!\n", i); 303 exit (1); 304 } 305 mpfr_set_ui (w, 0, MPFR_RNDN); 306 mpfr_nextabove (w); 307 test_mul (i, 1, w, w, 1, MPFR_RNDN); 308 if (mpfr_cmp_ui (w, 0)) 309 { 310 printf ("Underflow error (i = %d)!\n", i); 311 exit (1); 312 } 313 } 314 315 if (MPFR_EXP_MAX >= LONG_MAX/2 && MPFR_EXP_MIN <= LONG_MAX/2-LONG_MAX-1) 316 { 317 unsigned long lmp1 = (unsigned long) LONG_MAX + 1; 318 319 mpfr_set_ui (w, 1, MPFR_RNDN); 320 mpfr_mul_2ui (w, w, LONG_MAX/2, MPFR_RNDZ); 321 mpfr_div_2ui (w, w, lmp1, MPFR_RNDZ); 322 mpfr_mul_2ui (w, w, lmp1 - LONG_MAX/2, MPFR_RNDZ); 323 if (!mpfr_cmp_ui (w, 1)) 324 { 325 printf ("Underflow LONG_MAX error!\n"); 326 exit (1); 327 } 328 } 329 330 mpfr_clears (w, z, (mpfr_ptr) 0); 331 332 underflow0 (); 333 large0 (); 334 335 tests_end_mpfr (); 336 return 0; 337 } 338