1 /* Test file for mpfr_mul_ui. 2 3 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 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 void 29 check_inexact (mpfr_prec_t p) 30 { 31 mpfr_t x, y, z; 32 unsigned long u; 33 mpfr_prec_t q; 34 int inexact, cmp; 35 int rnd; 36 37 mpfr_init2 (x, p); 38 mpfr_init (y); 39 mpfr_init2 (z, p + mp_bits_per_limb); 40 mpfr_urandomb (x, RANDS); 41 u = randlimb (); 42 if (mpfr_mul_ui (z, x, u, MPFR_RNDN)) 43 { 44 printf ("Error: result should be exact\n"); 45 exit (1); 46 } 47 48 for (q = 2; q <= p; q++) 49 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 50 { 51 mpfr_set_prec (y, q); 52 inexact = mpfr_mul_ui (y, x, u, (mpfr_rnd_t) rnd); 53 cmp = mpfr_cmp (y, z); 54 if (((inexact == 0) && (cmp != 0)) || 55 ((inexact < 0) && (cmp >= 0)) || 56 ((inexact > 0) && (cmp <= 0))) 57 { 58 printf ("Wrong inexact flag for p=%u, q=%u, rnd=%s\n", 59 (unsigned int) p, (unsigned int) q, 60 mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 61 exit (1); 62 } 63 } 64 65 mpfr_set_prec (x, 2); 66 mpfr_set_ui (x, 1, MPFR_RNDN); 67 if (mpfr_mul_ui (x, x, 5, MPFR_RNDZ) == 0) 68 { 69 printf ("mul_ui(1, 5) cannot be exact with prec=2\n"); 70 exit (1); 71 } 72 73 mpfr_clear (x); 74 mpfr_clear (y); 75 mpfr_clear (z); 76 } 77 78 #define TEST_FUNCTION mpfr_mul_ui 79 #define INTEGER_TYPE unsigned long 80 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS) 81 #include "tgeneric_ui.c" 82 83 int 84 main (int argc, char *argv[]) 85 { 86 mpfr_t x, y; 87 unsigned int xprec, yprec, i; 88 mpfr_prec_t p; 89 mpfr_exp_t emax; 90 91 tests_start_mpfr (); 92 93 for (p=2; p<100; p++) 94 for (i=1; i<50; i++) 95 check_inexact (p); 96 97 mpfr_init2 (x, 53); 98 mpfr_init2 (y, 53); 99 100 /* checks that result is normalized */ 101 mpfr_set_str (y, "6.93147180559945286227e-01", 10, MPFR_RNDZ); 102 mpfr_mul_ui (x, y, 1, MPFR_RNDZ); 103 if (MPFR_MANT(x)[MPFR_PREC(x)/mp_bits_per_limb] >> (mp_bits_per_limb-1) == 0) 104 { 105 printf ("Error in mpfr_mul_ui: result not normalized\n"); 106 exit (1); 107 } 108 if (mpfr_cmp (x, y)) 109 { 110 printf ("Error in mpfr_mul_ui: 1*y != y\n"); 111 printf ("y= "); mpfr_print_binary (y); puts (""); 112 printf ("1*y="); mpfr_print_binary (x); puts (""); 113 exit (1); 114 } 115 116 mpfr_set_inf (x, 1); 117 mpfr_mul_ui (x, x, 3, MPFR_RNDU); 118 if (!mpfr_inf_p (x) || (mpfr_sgn (x) <= 0)) 119 { 120 printf ("Error in mpfr_mul_ui: +Inf*3 does not give +Inf\n"); 121 exit (1); 122 } 123 124 mpfr_set_inf (x, -1); 125 mpfr_mul_ui (x, x, 3, MPFR_RNDU); 126 if (!mpfr_inf_p (x) || (mpfr_sgn (x) >= 0)) 127 { 128 printf ("Error in mpfr_mul_ui: -Inf*3 does not give -Inf\n"); 129 exit (1); 130 } 131 132 mpfr_set_nan (x); 133 mpfr_mul_ui (x, x, 3, MPFR_RNDU); 134 if (!mpfr_nan_p(x)) 135 { 136 printf ("Error in mpfr_mul_ui: NaN*3 does not give NaN\n"); 137 exit (1); 138 } 139 140 mpfr_set_inf (x, 1); 141 mpfr_mul_ui (x, x, 0, MPFR_RNDU); 142 MPFR_ASSERTN(mpfr_nan_p (x)); 143 144 mpfr_set_ui (x, 1, MPFR_RNDU); 145 mpfr_mul_ui (x, x, 0, MPFR_RNDU); 146 MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x)); 147 148 emax = mpfr_get_emax (); 149 set_emax (0); 150 mpfr_set_str_binary (x, "0.1E0"); 151 mpfr_mul_ui (x, x, 2, MPFR_RNDN); 152 MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x)); 153 set_emax (emax); 154 155 mpfr_set_str (x, /*1.0/3.0*/ 156 "0.333333333333333333333333333333333", 10, MPFR_RNDZ); 157 mpfr_mul_ui (x, x, 3, MPFR_RNDU); 158 if (mpfr_cmp_ui (x, 1)) 159 { 160 printf ("Error in mpfr_mul_ui: U(Z(1/3)*3) does not give 1\n"); 161 exit (1); 162 } 163 164 /* checks sign is correct */ 165 mpfr_set_si (x, -2, MPFR_RNDZ); 166 mpfr_set_si (y, 3, MPFR_RNDZ); 167 mpfr_mul_ui(x, y, 4, MPFR_RNDZ); 168 if (mpfr_cmp_ui(x, 0) <= 0) 169 { 170 printf("Error in mpfr_mul_ui: 4*3.0 does not give a positive result:\n"); 171 mpfr_print_binary(x); puts (""); 172 printf("mpfr_cmp_ui(x, 0) = %d\n", mpfr_cmp_ui(x, 0)); 173 exit(1); 174 } 175 176 mpfr_set_prec (x, 9); 177 mpfr_set_prec (y, 9); 178 mpfr_set_str_binary (y, "0.100001111E9"); /* 271 */ 179 mpfr_mul_ui (x, y, 1335, MPFR_RNDN); 180 mpfr_set_str_binary (y, "0.101100001E19"); /* 361472 */ 181 if (mpfr_cmp (x, y)) 182 { 183 printf ("Error in mul_ui for 1335*(0.100001111E9)\n"); 184 printf ("got "); mpfr_print_binary (x); puts (""); 185 exit(1); 186 } 187 188 mpfr_set_prec(y, 100); 189 mpfr_set_prec(x, 100); 190 /* y = 1199781142214086656 */ 191 mpfr_set_str_binary(y, "0.1000010100110011110101001011110010101111000100001E61"); 192 mpfr_mul_ui(x, y, 121, MPFR_RNDD); 193 /* 121*y = 145173518207904485376, representable exactly */ 194 mpfr_set_str_binary(y, "0.1111101111010101111111100011010010111010111110110011001E67"); 195 if (mpfr_cmp(x, y)) 196 { 197 printf("Error for 121*y: expected result is:\n"); 198 mpfr_print_binary(y); puts (""); 199 } 200 201 mpfr_set_prec (x, 32); 202 mpfr_set_str_binary (x, "0.10000000000000000000000000000000E1"); 203 mpfr_set_prec (y, 93); 204 mpfr_mul_ui (y, x, 1, MPFR_RNDN); 205 206 mpfr_set_prec (x, 287); 207 mpfr_set_str_binary (x, "0.1111E7"); 208 mpfr_set_prec (y, 289); 209 mpfr_mul_ui (y, x, 6, MPFR_RNDN); 210 mpfr_set_str_binary (x, "0.101101E10"); 211 if (mpfr_cmp (x, y)) 212 { 213 printf ("Error for 6 * 120\n"); 214 exit (1); 215 } 216 217 mpfr_set_prec (x, 68); 218 mpfr_set_prec (y, 64); 219 mpfr_set_str (x, "2143861251406875.0", 10, MPFR_RNDN); 220 mpfr_mul_ui (y, x, 23, MPFR_RNDN); 221 mpfr_set_str_binary (x, "10101111001011100001100110101111110001010010011001101101.0"); 222 if (mpfr_cmp (x, y)) 223 { 224 printf ("Error for 23 * 2143861251406875.0\n"); 225 printf ("expected "); mpfr_print_binary (x); puts (""); 226 printf ("got "); mpfr_print_binary (y); puts (""); 227 exit (1); 228 } 229 230 231 for (xprec = 53; xprec <= 128; xprec++) 232 { 233 mpfr_set_prec (x, xprec); 234 mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2"); 235 for (yprec = 53; yprec <= 128; yprec++) 236 { 237 mpfr_set_prec (y, yprec); 238 mpfr_mul_ui (y, x, 1, MPFR_RNDN); 239 if (mpfr_cmp(x,y)) 240 { 241 printf ("multiplication by 1.0 fails for xprec=%u, yprec=%u\n", 242 xprec, yprec); 243 printf ("expected "); mpfr_print_binary (x); puts (""); 244 printf ("got "); mpfr_print_binary (y); puts (""); 245 exit (1); 246 } 247 } 248 } 249 250 mpfr_set_prec (x, 128); 251 mpfr_set_ui (x, 17, MPFR_RNDN); 252 mpfr_mul_ui (x, x, ULONG_HIGHBIT, MPFR_RNDN); 253 mpfr_set_prec (y, 128); 254 mpfr_set_ui (y, ULONG_HIGHBIT, MPFR_RNDN); 255 mpfr_mul_ui (y, y, 17, MPFR_RNDN); 256 if (mpfr_cmp (x, y)) 257 { 258 printf ("Error for 17 * ULONG_HIGHBIT\n"); 259 exit (1); 260 } 261 262 /* Check regression */ 263 mpfr_set_prec (x, 32); 264 mpfr_set_prec (y, 96); 265 mpfr_set_ui (x, 1742175942, MPFR_RNDN); 266 mpfr_mul_ui (y, x, 59, MPFR_RNDN); 267 if (mpfr_cmp_str (y, "0.10111111011101010101000110111101000100000000000000" 268 "0000000000000000000000000000000000000000000000E37", 269 2, MPFR_RNDN)) 270 { 271 printf ("Regression tested failed for x=1742175942 * 59\n"); 272 exit (1); 273 } 274 275 mpfr_clear(x); 276 mpfr_clear(y); 277 278 test_generic_ui (2, 500, 100); 279 280 tests_end_mpfr (); 281 return 0; 282 } 283