1 /* Test file for mpfr_{mul,div}_2{ui,si}. 2 3 Copyright 1999, 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 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 if (e >= LONG_MIN) 105 printf ("%ld", (long) e); 106 else 107 printf ("<LONG_MIN"); 108 printf (") with mpfr_%s,\nx = %d/16, prec = %d, k = %d, " 109 "%s\n", div == 0 ? "mul_2si" : div == 1 ? 110 "div_2si" : "div_2ui", i, prec, k, 111 mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 112 printf ("Expected "); 113 mpfr_out_str (stdout, 16, 0, z1, MPFR_RNDN); 114 printf (", inex = %d, flags = %u\n", SIGN (inex1), flags1); 115 printf ("Got "); 116 mpfr_out_str (stdout, 16, 0, z2, MPFR_RNDN); 117 printf (", inex = %d, flags = %u\n", SIGN (inex2), flags2); 118 exit (1); 119 } /* div */ 120 } /* k */ 121 mpfr_clears (z1, z2, (mpfr_ptr) 0); 122 } /* prec */ 123 } /* i */ 124 mpfr_clears (x, y, (mpfr_ptr) 0); 125 set_emin (emin); 126 } 127 128 static void 129 underflow0 (void) 130 { 131 underflow (-256); 132 if (mpfr_get_emin () != MPFR_EMIN_MIN) 133 underflow (mpfr_get_emin ()); 134 underflow (MPFR_EMIN_MIN); 135 } 136 137 static void 138 large (mpfr_exp_t e) 139 { 140 mpfr_t x, y, z; 141 mpfr_exp_t emax; 142 int inex; 143 unsigned int flags; 144 145 emax = mpfr_get_emax (); 146 set_emax (e); 147 mpfr_init2 (x, 8); 148 mpfr_init2 (y, 8); 149 mpfr_init2 (z, 4); 150 151 mpfr_set_inf (x, 1); 152 mpfr_nextbelow (x); 153 154 mpfr_mul_2si (y, x, -1, MPFR_RNDU); 155 mpfr_prec_round (y, 4, MPFR_RNDU); 156 157 mpfr_clear_flags (); 158 inex = mpfr_mul_2si (z, x, -1, MPFR_RNDU); 159 flags = __gmpfr_flags; 160 161 if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z)) 162 { 163 printf ("Error in large("); 164 if (e == MPFR_EMAX_MAX) 165 printf ("MPFR_EMAX_MAX"); 166 else if (e == emax) 167 printf ("default emax"); 168 else if (e <= LONG_MAX) 169 printf ("%ld", (long) e); 170 else 171 printf (">LONG_MAX"); 172 printf (") for mpfr_mul_2si\n"); 173 printf ("Expected inex > 0, flags = %u,\n y = ", 174 (unsigned int) MPFR_FLAGS_INEXACT); 175 mpfr_dump (y); 176 printf ("Got inex = %d, flags = %u,\n y = ", 177 inex, flags); 178 mpfr_dump (z); 179 exit (1); 180 } 181 182 mpfr_clear_flags (); 183 inex = mpfr_div_2si (z, x, 1, MPFR_RNDU); 184 flags = __gmpfr_flags; 185 186 if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z)) 187 { 188 printf ("Error in large("); 189 if (e == MPFR_EMAX_MAX) 190 printf ("MPFR_EMAX_MAX"); 191 else if (e == emax) 192 printf ("default emax"); 193 else if (e <= LONG_MAX) 194 printf ("%ld", (long) e); 195 else 196 printf (">LONG_MAX"); 197 printf (") for mpfr_div_2si\n"); 198 printf ("Expected inex > 0, flags = %u,\n y = ", 199 (unsigned int) MPFR_FLAGS_INEXACT); 200 mpfr_dump (y); 201 printf ("Got inex = %d, flags = %u,\n y = ", 202 inex, flags); 203 mpfr_dump (z); 204 exit (1); 205 } 206 207 mpfr_clear_flags (); 208 inex = mpfr_div_2ui (z, x, 1, MPFR_RNDU); 209 flags = __gmpfr_flags; 210 211 if (inex <= 0 || flags != MPFR_FLAGS_INEXACT || ! mpfr_equal_p (y, z)) 212 { 213 printf ("Error in large("); 214 if (e == MPFR_EMAX_MAX) 215 printf ("MPFR_EMAX_MAX"); 216 else if (e == emax) 217 printf ("default emax"); 218 else if (e <= LONG_MAX) 219 printf ("%ld", (long) e); 220 else 221 printf (">LONG_MAX"); 222 printf (") for mpfr_div_2ui\n"); 223 printf ("Expected inex > 0, flags = %u,\n y = ", 224 (unsigned int) MPFR_FLAGS_INEXACT); 225 mpfr_dump (y); 226 printf ("Got inex = %d, flags = %u,\n y = ", 227 inex, flags); 228 mpfr_dump (z); 229 exit (1); 230 } 231 232 mpfr_clears (x, y, z, (mpfr_ptr) 0); 233 set_emax (emax); 234 } 235 236 static void 237 large0 (void) 238 { 239 large (256); 240 if (mpfr_get_emax () != MPFR_EMAX_MAX) 241 large (mpfr_get_emax ()); 242 large (MPFR_EMAX_MAX); 243 } 244 245 int 246 main (int argc, char *argv[]) 247 { 248 mpfr_t w,z; 249 unsigned long k; 250 int i; 251 252 tests_start_mpfr (); 253 254 mpfr_inits2 (53, w, z, (mpfr_ptr) 0); 255 256 for (i = 0; i < 3; i++) 257 { 258 mpfr_set_inf (w, 1); 259 test_mul (i, 0, w, w, 10, MPFR_RNDZ); 260 if (!MPFR_IS_INF(w)) 261 { 262 printf ("Result is not Inf (i = %d)\n", i); 263 exit (1); 264 } 265 266 mpfr_set_nan (w); 267 test_mul (i, 0, w, w, 10, MPFR_RNDZ); 268 if (!MPFR_IS_NAN(w)) 269 { 270 printf ("Result is not NaN (i = %d)\n", i); 271 exit (1); 272 } 273 274 for (k = 0 ; k < numberof(val) ; k+=3) 275 { 276 mpfr_set_str (w, val[k], 16, MPFR_RNDN); 277 test_mul (i, 0, z, w, 10, MPFR_RNDZ); 278 if (mpfr_cmp_str (z, val[k+1], 16, MPFR_RNDN)) 279 { 280 printf ("ERROR for x * 2^n (i = %d) for %s\n", i, val[k]); 281 printf ("Expected: %s\n" 282 "Got : ", val[k+1]); 283 mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); 284 putchar ('\n'); 285 exit (1); 286 } 287 test_mul (i, 1, z, w, 10, MPFR_RNDZ); 288 if (mpfr_cmp_str (z, val[k+2], 16, MPFR_RNDN)) 289 { 290 printf ("ERROR for x / 2^n (i = %d) for %s\n", i, val[k]); 291 printf ("Expected: %s\n" 292 "Got : ", val[k+2]); 293 mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); 294 putchar ('\n'); 295 exit (1); 296 } 297 } 298 299 mpfr_set_inf (w, 1); 300 mpfr_nextbelow (w); 301 test_mul (i, 0, w, w, 1, MPFR_RNDN); 302 if (!mpfr_inf_p (w)) 303 { 304 printf ("Overflow error (i = %d)!\n", i); 305 exit (1); 306 } 307 mpfr_set_ui (w, 0, MPFR_RNDN); 308 mpfr_nextabove (w); 309 test_mul (i, 1, w, w, 1, MPFR_RNDN); 310 if (mpfr_cmp_ui (w, 0)) 311 { 312 printf ("Underflow error (i = %d)!\n", i); 313 exit (1); 314 } 315 } 316 317 if (MPFR_EXP_MAX >= LONG_MAX/2 && MPFR_EXP_MIN <= LONG_MAX/2-LONG_MAX-1) 318 { 319 unsigned long lmp1 = (unsigned long) LONG_MAX + 1; 320 321 mpfr_set_ui (w, 1, MPFR_RNDN); 322 mpfr_mul_2ui (w, w, LONG_MAX/2, MPFR_RNDZ); 323 mpfr_div_2ui (w, w, lmp1, MPFR_RNDZ); 324 mpfr_mul_2ui (w, w, lmp1 - LONG_MAX/2, MPFR_RNDZ); 325 if (!mpfr_cmp_ui (w, 1)) 326 { 327 printf ("Underflow LONG_MAX error!\n"); 328 exit (1); 329 } 330 } 331 332 mpfr_clears (w, z, (mpfr_ptr) 0); 333 334 underflow0 (); 335 large0 (); 336 337 tests_end_mpfr (); 338 return 0; 339 } 340