| OLD | NEW |
| (Empty) |
| 1 /* Test file for mpfr_mul. | |
| 2 | |
| 3 Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Softwa
re 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 2.1 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.LIB. If not, write to | |
| 20 the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, | |
| 21 MA 02110-1301, USA. */ | |
| 22 | |
| 23 #include <stdio.h> | |
| 24 #include <stdlib.h> | |
| 25 | |
| 26 #include "mpfr-test.h" | |
| 27 | |
| 28 #ifndef MPFR_SRCDIR | |
| 29 #define MPFR_SRCDIR . | |
| 30 #endif | |
| 31 #define QUOTE(X) NAME(X) | |
| 32 #define NAME(X) #X | |
| 33 | |
| 34 #ifdef CHECK_EXTERNAL | |
| 35 static int | |
| 36 test_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode) | |
| 37 { | |
| 38 int res; | |
| 39 int ok = rnd_mode == GMP_RNDN && mpfr_number_p (b) && mpfr_number_p (c); | |
| 40 if (ok) | |
| 41 { | |
| 42 mpfr_print_raw (b); | |
| 43 printf (" "); | |
| 44 mpfr_print_raw (c); | |
| 45 } | |
| 46 res = mpfr_mul (a, b, c, rnd_mode); | |
| 47 if (ok) | |
| 48 { | |
| 49 printf (" "); | |
| 50 mpfr_print_raw (a); | |
| 51 printf ("\n"); | |
| 52 } | |
| 53 return res; | |
| 54 } | |
| 55 #else | |
| 56 #define test_mul mpfr_mul | |
| 57 #endif | |
| 58 | |
| 59 /* Workaround for sparc gcc 2.95.x bug, see notes in tadd.c. */ | |
| 60 #define check(x,y,rnd_mode,px,py,pz,res) pcheck(x,y,res,rnd_mode,px,py,pz) | |
| 61 | |
| 62 /* checks that x*y gives the right result */ | |
| 63 static void | |
| 64 pcheck (const char *xs, const char *ys, const char *res, mp_rnd_t rnd_mode, | |
| 65 unsigned int px, unsigned int py, unsigned int pz) | |
| 66 { | |
| 67 mpfr_t xx, yy, zz; | |
| 68 | |
| 69 mpfr_init2 (xx, px); | |
| 70 mpfr_init2 (yy, py); | |
| 71 mpfr_init2 (zz, pz); | |
| 72 mpfr_set_str1 (xx, xs); | |
| 73 mpfr_set_str1 (yy, ys); | |
| 74 test_mul(zz, xx, yy, rnd_mode); | |
| 75 if (mpfr_cmp_str1 (zz, res) ) | |
| 76 { | |
| 77 printf ("(1)mpfr_mul failed for x=%s y=%s with rnd=%s\n", | |
| 78 xs, ys, mpfr_print_rnd_mode (rnd_mode)); | |
| 79 printf ("correct is %s, mpfr_mul gives ", res); | |
| 80 mpfr_out_str(stdout, 10, 0, zz, GMP_RNDN); | |
| 81 /* | |
| 82 printf("\nBinary forms:\nxx="); | |
| 83 mpfr_print_binary (xx); | |
| 84 printf("\nyy="); | |
| 85 mpfr_print_binary (yy); | |
| 86 printf("\nzz="); | |
| 87 mpfr_print_binary(zz); | |
| 88 printf("\nre="); | |
| 89 mpfr_set_str1 (zz, res); | |
| 90 mpfr_print_binary(zz); | |
| 91 putchar('\n');*/ | |
| 92 exit (1); | |
| 93 } | |
| 94 mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz); | |
| 95 } | |
| 96 | |
| 97 static void | |
| 98 check53 (const char *xs, const char *ys, mp_rnd_t rnd_mode, const char *zs) | |
| 99 { | |
| 100 mpfr_t xx, yy, zz; | |
| 101 | |
| 102 mpfr_inits2 (53, xx, yy, zz, (mpfr_ptr) 0); | |
| 103 mpfr_set_str1 (xx, xs); | |
| 104 mpfr_set_str1 (yy, ys); | |
| 105 test_mul (zz, xx, yy, rnd_mode); | |
| 106 if (mpfr_cmp_str1 (zz, zs) ) | |
| 107 { | |
| 108 printf ("(2) mpfr_mul failed for x=%s y=%s with rnd=%s\n", | |
| 109 xs, ys, mpfr_print_rnd_mode(rnd_mode)); | |
| 110 printf ("correct result is %s,\n mpfr_mul gives ", zs); | |
| 111 mpfr_out_str(stdout, 10, 0, zz, GMP_RNDN); | |
| 112 /* | |
| 113 printf("\nBinary forms:\nxx="); | |
| 114 mpfr_print_binary (xx); | |
| 115 printf("\nyy="); | |
| 116 mpfr_print_binary (yy); | |
| 117 printf("\nzz="); | |
| 118 mpfr_print_binary(zz); | |
| 119 printf("\nre="); | |
| 120 mpfr_set_str1 (zz, zs); | |
| 121 mpfr_print_binary(zz); | |
| 122 putchar('\n'); */ | |
| 123 exit (1); | |
| 124 } | |
| 125 mpfr_clears (xx, yy, zz, (mpfr_ptr) 0); | |
| 126 } | |
| 127 | |
| 128 /* checks that x*y gives the right result with 24 bits of precision */ | |
| 129 static void | |
| 130 check24 (const char *xs, const char *ys, mp_rnd_t rnd_mode, const char *zs) | |
| 131 { | |
| 132 mpfr_t xx, yy, zz; | |
| 133 | |
| 134 mpfr_inits2 (24, xx, yy, zz, (mpfr_ptr) 0); | |
| 135 mpfr_set_str1 (xx, xs); | |
| 136 mpfr_set_str1 (yy, ys); | |
| 137 test_mul (zz, xx, yy, rnd_mode); | |
| 138 if (mpfr_cmp_str1 (zz, zs) ) | |
| 139 { | |
| 140 printf ("(3) mpfr_mul failed for x=%s y=%s with " | |
| 141 "rnd=%s\n", xs, ys, mpfr_print_rnd_mode(rnd_mode)); | |
| 142 printf ("correct result is gives %s, mpfr_mul gives ", zs); | |
| 143 mpfr_out_str(stdout, 10, 0, zz, GMP_RNDN); | |
| 144 putchar('\n'); | |
| 145 exit (1); | |
| 146 } | |
| 147 mpfr_clears (xx, yy, zz, (mpfr_ptr) 0); | |
| 148 } | |
| 149 | |
| 150 /* the following examples come from the paper "Number-theoretic Test | |
| 151 Generation for Directed Rounding" from Michael Parks, Table 1 */ | |
| 152 static void | |
| 153 check_float (void) | |
| 154 { | |
| 155 check24("8388609.0", "8388609.0", GMP_RNDN, "70368760954880.0"); | |
| 156 check24("16777213.0", "8388609.0", GMP_RNDN, "140737479966720.0"); | |
| 157 check24("8388611.0", "8388609.0", GMP_RNDN, "70368777732096.0"); | |
| 158 check24("12582911.0", "8388610.0", GMP_RNDN, "105553133043712.0"); | |
| 159 check24("12582914.0", "8388610.0", GMP_RNDN, "105553158209536.0"); | |
| 160 check24("13981013.0", "8388611.0", GMP_RNDN, "117281279442944.0"); | |
| 161 check24("11184811.0", "8388611.0", GMP_RNDN, "93825028587520.0"); | |
| 162 check24("11184810.0", "8388611.0", GMP_RNDN, "93825020198912.0"); | |
| 163 check24("13981014.0", "8388611.0", GMP_RNDN, "117281287831552.0"); | |
| 164 | |
| 165 check24("8388609.0", "8388609.0", GMP_RNDZ, "70368760954880.0"); | |
| 166 check24("16777213.0", "8388609.0", GMP_RNDZ, "140737471578112.0"); | |
| 167 check24("8388611.0", "8388609.0", GMP_RNDZ, "70368777732096.0"); | |
| 168 check24("12582911.0", "8388610.0", GMP_RNDZ, "105553124655104.0"); | |
| 169 check24("12582914.0", "8388610.0", GMP_RNDZ, "105553158209536.0"); | |
| 170 check24("13981013.0", "8388611.0", GMP_RNDZ, "117281271054336.0"); | |
| 171 check24("11184811.0", "8388611.0", GMP_RNDZ, "93825028587520.0"); | |
| 172 check24("11184810.0", "8388611.0", GMP_RNDZ, "93825011810304.0"); | |
| 173 check24("13981014.0", "8388611.0", GMP_RNDZ, "117281287831552.0"); | |
| 174 | |
| 175 check24("8388609.0", "8388609.0", GMP_RNDU, "70368769343488.0"); | |
| 176 check24("16777213.0", "8388609.0", GMP_RNDU, "140737479966720.0"); | |
| 177 check24("8388611.0", "8388609.0", GMP_RNDU, "70368786120704.0"); | |
| 178 check24("12582911.0", "8388610.0", GMP_RNDU, "105553133043712.0"); | |
| 179 check24("12582914.0", "8388610.0", GMP_RNDU, "105553166598144.0"); | |
| 180 check24("13981013.0", "8388611.0", GMP_RNDU, "117281279442944.0"); | |
| 181 check24("11184811.0", "8388611.0", GMP_RNDU, "93825036976128.0"); | |
| 182 check24("11184810.0", "8388611.0", GMP_RNDU, "93825020198912.0"); | |
| 183 check24("13981014.0", "8388611.0", GMP_RNDU, "117281296220160.0"); | |
| 184 | |
| 185 check24("8388609.0", "8388609.0", GMP_RNDD, "70368760954880.0"); | |
| 186 check24("16777213.0", "8388609.0", GMP_RNDD, "140737471578112.0"); | |
| 187 check24("8388611.0", "8388609.0", GMP_RNDD, "70368777732096.0"); | |
| 188 check24("12582911.0", "8388610.0", GMP_RNDD, "105553124655104.0"); | |
| 189 check24("12582914.0", "8388610.0", GMP_RNDD, "105553158209536.0"); | |
| 190 check24("13981013.0", "8388611.0", GMP_RNDD, "117281271054336.0"); | |
| 191 check24("11184811.0", "8388611.0", GMP_RNDD, "93825028587520.0"); | |
| 192 check24("11184810.0", "8388611.0", GMP_RNDD, "93825011810304.0"); | |
| 193 check24("13981014.0", "8388611.0", GMP_RNDD, "117281287831552.0"); | |
| 194 } | |
| 195 | |
| 196 /* check sign of result */ | |
| 197 static void | |
| 198 check_sign (void) | |
| 199 { | |
| 200 mpfr_t a, b; | |
| 201 | |
| 202 mpfr_init2 (a, 53); | |
| 203 mpfr_init2 (b, 53); | |
| 204 mpfr_set_si (a, -1, GMP_RNDN); | |
| 205 mpfr_set_ui (b, 2, GMP_RNDN); | |
| 206 test_mul(a, b, b, GMP_RNDN); | |
| 207 if (mpfr_cmp_ui (a, 4) ) | |
| 208 { | |
| 209 printf ("2.0*2.0 gives \n"); | |
| 210 mpfr_out_str(stdout, 10, 0, a, GMP_RNDN); | |
| 211 putchar('\n'); | |
| 212 exit (1); | |
| 213 } | |
| 214 mpfr_clear(a); mpfr_clear(b); | |
| 215 } | |
| 216 | |
| 217 /* checks that the inexact return value is correct */ | |
| 218 static void | |
| 219 check_exact (void) | |
| 220 { | |
| 221 mpfr_t a, b, c, d; | |
| 222 mp_prec_t prec; | |
| 223 int i, inexact; | |
| 224 mp_rnd_t rnd; | |
| 225 | |
| 226 mpfr_init (a); | |
| 227 mpfr_init (b); | |
| 228 mpfr_init (c); | |
| 229 mpfr_init (d); | |
| 230 | |
| 231 mpfr_set_prec (a, 17); | |
| 232 mpfr_set_prec (b, 17); | |
| 233 mpfr_set_prec (c, 32); | |
| 234 mpfr_set_str_binary (a, "1.1000111011000100e-1"); | |
| 235 mpfr_set_str_binary (b, "1.0010001111100111e-1"); | |
| 236 if (test_mul (c, a, b, GMP_RNDZ)) | |
| 237 { | |
| 238 printf ("wrong return value (1)\n"); | |
| 239 exit (1); | |
| 240 } | |
| 241 | |
| 242 for (prec = 2; prec < 100; prec++) | |
| 243 { | |
| 244 mpfr_set_prec (a, prec); | |
| 245 mpfr_set_prec (b, prec); | |
| 246 mpfr_set_prec (c, 2 * prec - 2); | |
| 247 mpfr_set_prec (d, 2 * prec); | |
| 248 for (i = 0; i < 1000; i++) | |
| 249 { | |
| 250 mpfr_urandomb (a, RANDS); | |
| 251 mpfr_urandomb (b, RANDS); | |
| 252 rnd = RND_RAND (); | |
| 253 inexact = test_mul (c, a, b, rnd); | |
| 254 if (test_mul (d, a, b, rnd)) /* should be always exact */ | |
| 255 { | |
| 256 printf ("unexpected inexact return value\n"); | |
| 257 exit (1); | |
| 258 } | |
| 259 if ((inexact == 0) && mpfr_cmp (c, d)) | |
| 260 { | |
| 261 printf ("inexact=0 but results differ\n"); | |
| 262 exit (1); | |
| 263 } | |
| 264 else if (inexact && (mpfr_cmp (c, d) == 0)) | |
| 265 { | |
| 266 printf ("inexact!=0 but results agree\n"); | |
| 267 printf ("prec=%u rnd=%s a=", (unsigned int) prec, | |
| 268 mpfr_print_rnd_mode (rnd)); | |
| 269 mpfr_out_str (stdout, 2, 0, a, rnd); | |
| 270 printf ("\nb="); | |
| 271 mpfr_out_str (stdout, 2, 0, b, rnd); | |
| 272 printf ("\nc="); | |
| 273 mpfr_out_str (stdout, 2, 0, c, rnd); | |
| 274 printf ("\nd="); | |
| 275 mpfr_out_str (stdout, 2, 0, d, rnd); | |
| 276 printf ("\n"); | |
| 277 exit (1); | |
| 278 } | |
| 279 } | |
| 280 } | |
| 281 | |
| 282 mpfr_clear (a); | |
| 283 mpfr_clear (b); | |
| 284 mpfr_clear (c); | |
| 285 mpfr_clear (d); | |
| 286 } | |
| 287 | |
| 288 static void | |
| 289 check_max(void) | |
| 290 { | |
| 291 mpfr_t xx, yy, zz; | |
| 292 mp_exp_t emin; | |
| 293 | |
| 294 mpfr_init2(xx, 4); | |
| 295 mpfr_init2(yy, 4); | |
| 296 mpfr_init2(zz, 4); | |
| 297 mpfr_set_str1 (xx, "0.68750"); | |
| 298 mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT/2, GMP_RNDN); | |
| 299 mpfr_set_str1 (yy, "0.68750"); | |
| 300 mpfr_mul_2si(yy, yy, MPFR_EMAX_DEFAULT - MPFR_EMAX_DEFAULT/2 + 1, GMP_RNDN); | |
| 301 mpfr_clear_flags(); | |
| 302 test_mul(zz, xx, yy, GMP_RNDU); | |
| 303 if (!(mpfr_overflow_p() && MPFR_IS_INF(zz))) | |
| 304 { | |
| 305 printf("check_max failed (should be an overflow)\n"); | |
| 306 exit(1); | |
| 307 } | |
| 308 | |
| 309 mpfr_clear_flags(); | |
| 310 test_mul(zz, xx, yy, GMP_RNDD); | |
| 311 if (mpfr_overflow_p() || MPFR_IS_INF(zz)) | |
| 312 { | |
| 313 printf("check_max failed (should NOT be an overflow)\n"); | |
| 314 exit(1); | |
| 315 } | |
| 316 mpfr_set_str1 (xx, "0.93750"); | |
| 317 mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT, GMP_RNDN); | |
| 318 if (!(MPFR_IS_FP(xx) && MPFR_IS_FP(zz))) | |
| 319 { | |
| 320 printf("check_max failed (internal error)\n"); | |
| 321 exit(1); | |
| 322 } | |
| 323 if (mpfr_cmp(xx, zz) != 0) | |
| 324 { | |
| 325 printf("check_max failed: got "); | |
| 326 mpfr_out_str(stdout, 2, 0, zz, GMP_RNDZ); | |
| 327 printf(" instead of "); | |
| 328 mpfr_out_str(stdout, 2, 0, xx, GMP_RNDZ); | |
| 329 printf("\n"); | |
| 330 exit(1); | |
| 331 } | |
| 332 | |
| 333 /* check underflow */ | |
| 334 emin = mpfr_get_emin (); | |
| 335 set_emin (0); | |
| 336 mpfr_set_str_binary (xx, "0.1E0"); | |
| 337 mpfr_set_str_binary (yy, "0.1E0"); | |
| 338 test_mul (zz, xx, yy, GMP_RNDN); | |
| 339 /* exact result is 0.1E-1, which should round to 0 */ | |
| 340 MPFR_ASSERTN(mpfr_cmp_ui (zz, 0) == 0 && MPFR_IS_POS(zz)); | |
| 341 set_emin (emin); | |
| 342 | |
| 343 /* coverage test for mpfr_powerof2_raw */ | |
| 344 emin = mpfr_get_emin (); | |
| 345 set_emin (0); | |
| 346 mpfr_set_prec (xx, mp_bits_per_limb + 1); | |
| 347 mpfr_set_str_binary (xx, "0.1E0"); | |
| 348 mpfr_nextabove (xx); | |
| 349 mpfr_set_str_binary (yy, "0.1E0"); | |
| 350 test_mul (zz, xx, yy, GMP_RNDN); | |
| 351 /* exact result is just above 0.1E-1, which should round to minfloat */ | |
| 352 MPFR_ASSERTN(mpfr_cmp (zz, yy) == 0); | |
| 353 set_emin (emin); | |
| 354 | |
| 355 mpfr_clear(xx); | |
| 356 mpfr_clear(yy); | |
| 357 mpfr_clear(zz); | |
| 358 } | |
| 359 | |
| 360 static void | |
| 361 check_min(void) | |
| 362 { | |
| 363 mpfr_t xx, yy, zz; | |
| 364 | |
| 365 mpfr_init2(xx, 4); | |
| 366 mpfr_init2(yy, 4); | |
| 367 mpfr_init2(zz, 3); | |
| 368 mpfr_set_str1(xx, "0.9375"); | |
| 369 mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT/2, GMP_RNDN); | |
| 370 mpfr_set_str1(yy, "0.9375"); | |
| 371 mpfr_mul_2si(yy, yy, MPFR_EMIN_DEFAULT - MPFR_EMIN_DEFAULT/2 - 1, GMP_RNDN); | |
| 372 test_mul(zz, xx, yy, GMP_RNDD); | |
| 373 if (mpfr_sgn(zz) != 0) | |
| 374 { | |
| 375 printf("check_min failed: got "); | |
| 376 mpfr_out_str(stdout, 2, 0, zz, GMP_RNDZ); | |
| 377 printf(" instead of 0\n"); | |
| 378 exit(1); | |
| 379 } | |
| 380 | |
| 381 test_mul(zz, xx, yy, GMP_RNDU); | |
| 382 mpfr_set_str1 (xx, "0.5"); | |
| 383 mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT, GMP_RNDN); | |
| 384 if (mpfr_sgn(xx) <= 0) | |
| 385 { | |
| 386 printf("check_min failed (internal error)\n"); | |
| 387 exit(1); | |
| 388 } | |
| 389 if (mpfr_cmp(xx, zz) != 0) | |
| 390 { | |
| 391 printf("check_min failed: got "); | |
| 392 mpfr_out_str(stdout, 2, 0, zz, GMP_RNDZ); | |
| 393 printf(" instead of "); | |
| 394 mpfr_out_str(stdout, 2, 0, xx, GMP_RNDZ); | |
| 395 printf("\n"); | |
| 396 exit(1); | |
| 397 } | |
| 398 | |
| 399 mpfr_clear(xx); | |
| 400 mpfr_clear(yy); | |
| 401 mpfr_clear(zz); | |
| 402 } | |
| 403 | |
| 404 static void | |
| 405 check_nans (void) | |
| 406 { | |
| 407 mpfr_t p, x, y; | |
| 408 | |
| 409 mpfr_init2 (x, 123L); | |
| 410 mpfr_init2 (y, 123L); | |
| 411 mpfr_init2 (p, 123L); | |
| 412 | |
| 413 /* nan * 0 == nan */ | |
| 414 mpfr_set_nan (x); | |
| 415 mpfr_set_ui (y, 0L, GMP_RNDN); | |
| 416 test_mul (p, x, y, GMP_RNDN); | |
| 417 MPFR_ASSERTN (mpfr_nan_p (p)); | |
| 418 | |
| 419 /* 1 * nan == nan */ | |
| 420 mpfr_set_ui (x, 1L, GMP_RNDN); | |
| 421 mpfr_set_nan (y); | |
| 422 test_mul (p, x, y, GMP_RNDN); | |
| 423 MPFR_ASSERTN (mpfr_nan_p (p)); | |
| 424 | |
| 425 /* 0 * +inf == nan */ | |
| 426 mpfr_set_ui (x, 0L, GMP_RNDN); | |
| 427 mpfr_set_nan (y); | |
| 428 test_mul (p, x, y, GMP_RNDN); | |
| 429 MPFR_ASSERTN (mpfr_nan_p (p)); | |
| 430 | |
| 431 /* +1 * +inf == +inf */ | |
| 432 mpfr_set_ui (x, 1L, GMP_RNDN); | |
| 433 mpfr_set_inf (y, 1); | |
| 434 test_mul (p, x, y, GMP_RNDN); | |
| 435 MPFR_ASSERTN (mpfr_inf_p (p)); | |
| 436 MPFR_ASSERTN (mpfr_sgn (p) > 0); | |
| 437 | |
| 438 /* -1 * +inf == -inf */ | |
| 439 mpfr_set_si (x, -1L, GMP_RNDN); | |
| 440 mpfr_set_inf (y, 1); | |
| 441 test_mul (p, x, y, GMP_RNDN); | |
| 442 MPFR_ASSERTN (mpfr_inf_p (p)); | |
| 443 MPFR_ASSERTN (mpfr_sgn (p) < 0); | |
| 444 | |
| 445 mpfr_clear (x); | |
| 446 mpfr_clear (y); | |
| 447 mpfr_clear (p); | |
| 448 } | |
| 449 | |
| 450 #define BUFSIZE 1552 | |
| 451 | |
| 452 static void | |
| 453 get_string (char *s, FILE *fp) | |
| 454 { | |
| 455 int c, n = BUFSIZE; | |
| 456 | |
| 457 while ((c = getc (fp)) != '\n') | |
| 458 { | |
| 459 if (c == EOF) | |
| 460 { | |
| 461 printf ("Error in get_string: end of file\n"); | |
| 462 exit (1); | |
| 463 } | |
| 464 *(unsigned char *)s++ = c; | |
| 465 if (--n == 0) | |
| 466 { | |
| 467 printf ("Error in get_string: buffer is too small\n"); | |
| 468 exit (1); | |
| 469 } | |
| 470 } | |
| 471 *s = '\0'; | |
| 472 } | |
| 473 | |
| 474 static void | |
| 475 check_regression (void) | |
| 476 { | |
| 477 mpfr_t x, y, z; | |
| 478 int i; | |
| 479 FILE *fp; | |
| 480 char s[BUFSIZE]; | |
| 481 | |
| 482 mpfr_inits2 (6177, x, y, z, (mpfr_ptr) 0); | |
| 483 /* we read long strings from a file since ISO C90 does not support strings of | |
| 484 length > 509 */ | |
| 485 fp = fopen (QUOTE (MPFR_SRCDIR)"/tmul.dat", "r"); | |
| 486 if (fp == NULL) | |
| 487 { | |
| 488 fprintf (stderr, "Error, cannot open "QUOTE (MPFR_SRCDIR)"/tmul.dat\n"); | |
| 489 exit (1); | |
| 490 } | |
| 491 get_string (s, fp); | |
| 492 mpfr_set_str (y, s, 16, GMP_RNDN); | |
| 493 get_string (s, fp); | |
| 494 mpfr_set_str (z, s, 16, GMP_RNDN); | |
| 495 i = mpfr_mul (x, y, z, GMP_RNDN); | |
| 496 get_string (s, fp); | |
| 497 if (mpfr_cmp_str (x, s, 16, GMP_RNDN) != 0 || i != -1) | |
| 498 { | |
| 499 printf ("Regression test 1 failed (i=%d, expected -1)\nx=", i); | |
| 500 mpfr_out_str (stdout, 16, 0, x, GMP_RNDN); putchar ('\n'); | |
| 501 exit (1); | |
| 502 } | |
| 503 fclose (fp); | |
| 504 | |
| 505 mpfr_set_prec (x, 606); | |
| 506 mpfr_set_prec (y, 606); | |
| 507 mpfr_set_prec (z, 606); | |
| 508 | |
| 509 mpfr_set_str (y, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f587365
64d9e93e62d324@-1", 16, GMP_RNDN); | |
| 510 mpfr_set_str (z, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffffff
fffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f587365
64d9e93e62d324@-1", 16, GMP_RNDN); | |
| 511 i = mpfr_mul (x, y, z, GMP_RNDU); | |
| 512 mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffff25b5df87f00a5953eb0e6cac
9b3d27cc5a64c@-1", 16, GMP_RNDN); | |
| 513 if (mpfr_cmp (x, y) || i <= 0) | |
| 514 { | |
| 515 printf ("Regression test (2) failed! (i=%d - Expected 1)\n", i); | |
| 516 mpfr_out_str (stdout, 16, 0, x, GMP_RNDN); putchar ('\n'); | |
| 517 exit (1); | |
| 518 } | |
| 519 | |
| 520 mpfr_set_prec (x, 184); | |
| 521 mpfr_set_prec (y, 92); | |
| 522 mpfr_set_prec (z, 1023); | |
| 523 | |
| 524 mpfr_set_str (y, "6.9b8c8498882770d8038c3b0@-1", 16, GMP_RNDN); | |
| 525 mpfr_set_str (z, "7.44e24b986e7fb296f1e936ce749fec3504cbf0d5ba769466b1c9f15781
15efd5d29b4c79271191a920a99280c714d3a657ad6e3afbab77ffce9d697e9bb9110e26d676069a
fcea8b69f1d1541f2365042d80a97c21dcccd8ace4f1bb58b49922003e738e6f37bb82ef653cb2e8
7f763974e6ae50ae54e7724c38b80653e3289@255", 16, GMP_RNDN); | |
| 526 i = mpfr_mul (x, y, z, GMP_RNDU); | |
| 527 mpfr_set_prec (y, 184); | |
| 528 mpfr_set_str (y, "3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255", | |
| 529 16, GMP_RNDN); | |
| 530 if (mpfr_cmp (x, y) || i <= 0) | |
| 531 { | |
| 532 printf ("Regression test (4) failed! (i=%d - expected 1)\n", i); | |
| 533 printf ("Ref: 3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255\n" | |
| 534 "Got: "); | |
| 535 mpfr_out_str (stdout, 16, 0, x, GMP_RNDN); | |
| 536 printf ("\n"); | |
| 537 exit (1); | |
| 538 } | |
| 539 | |
| 540 mpfr_set_prec (x, 908); | |
| 541 mpfr_set_prec (y, 908); | |
| 542 mpfr_set_prec (z, 908); | |
| 543 mpfr_set_str (y, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
| 544 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
| 545 "ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42" | |
| 546 "e6e9a327230345ea6@-1", 16, GMP_RNDN); | |
| 547 mpfr_set_str (z, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
| 548 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
| 549 "ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42" | |
| 550 "e6e9a327230345ea6@-1", 16, GMP_RNDN); | |
| 551 i = mpfr_mul (x, y, z, GMP_RNDU); | |
| 552 mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
| 553 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" | |
| 554 "fffffffffffffffffffffffffffffffffffffffffffffffffffff337d23f07d8de1da5147a85c" | |
| 555 "dd3464e46068bd4d@-1", 16, GMP_RNDN); | |
| 556 if (mpfr_cmp (x, y) || i <= 0) | |
| 557 { | |
| 558 printf ("Regression test (5) failed! (i=%d - expected 1)\n", i); | |
| 559 mpfr_out_str (stdout, 16, 0, x, GMP_RNDN); | |
| 560 printf ("\n"); | |
| 561 exit (1); | |
| 562 } | |
| 563 | |
| 564 | |
| 565 mpfr_set_prec (x, 50); | |
| 566 mpfr_set_prec (y, 40); | |
| 567 mpfr_set_prec (z, 53); | |
| 568 mpfr_set_str (y, "4.1ffffffff8", 16, GMP_RNDN); | |
| 569 mpfr_set_str (z, "4.2000000ffe0000@-4", 16, GMP_RNDN); | |
| 570 i = mpfr_mul (x, y, z, GMP_RNDN); | |
| 571 if (mpfr_cmp_str (x, "1.104000041d6c0@-3", 16, GMP_RNDN) != 0 | |
| 572 || i <= 0) | |
| 573 { | |
| 574 printf ("Regression test (6) failed! (i=%d - expected 1)\nx=", i); | |
| 575 mpfr_out_str (stdout, 16, 0, x, GMP_RNDN); | |
| 576 printf ("\nMore prec="); | |
| 577 mpfr_set_prec (x, 93); | |
| 578 mpfr_mul (x, y, z, GMP_RNDN); | |
| 579 mpfr_out_str (stdout, 16, 0, x, GMP_RNDN); | |
| 580 printf ("\n"); | |
| 581 exit (1); | |
| 582 } | |
| 583 | |
| 584 mpfr_set_prec (x, 439); | |
| 585 mpfr_set_prec (y, 393); | |
| 586 mpfr_set_str (y, "-1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d" | |
| 587 "4c76273644a29410f31c6809bbdf2a33679a748636600", | |
| 588 16, GMP_RNDN); | |
| 589 i = mpfr_mul (x, y, y, GMP_RNDU); | |
| 590 if (mpfr_cmp_str (x, "2.77a79937c8bbcb495b89b36602306b1c2159a8ff834288a19a08" | |
| 591 "84094f1cda3dc426da61174c4544a173de83c2500f8bfea2e0569e3698", | |
| 592 16, GMP_RNDN) != 0 | |
| 593 || i <= 0) | |
| 594 { | |
| 595 printf ("Regression test (7) failed! (i=%d - expected 1)\nx=", i); | |
| 596 mpfr_out_str (stdout, 16, 0, x, GMP_RNDN); | |
| 597 printf ("\n"); | |
| 598 exit (1); | |
| 599 } | |
| 600 | |
| 601 mpfr_set_prec (x, 1023); | |
| 602 mpfr_set_prec (y, 1023); | |
| 603 mpfr_set_prec (z, 511); | |
| 604 mpfr_set_ui (x, 17, GMP_RNDN); | |
| 605 mpfr_set_ui (y, 42, GMP_RNDN); | |
| 606 i = mpfr_mul (z, x, y, GMP_RNDN); | |
| 607 if (mpfr_cmp_ui (z, 17*42) != 0 || i != 0) | |
| 608 { | |
| 609 printf ("Regression test (8) failed! (i=%d - expected 0)\nz=", i); | |
| 610 mpfr_out_str (stdout, 16, 0, z, GMP_RNDN); | |
| 611 printf ("\n"); | |
| 612 exit (1); | |
| 613 } | |
| 614 | |
| 615 mpfr_clears (x, y, z, (mpfr_ptr) 0); | |
| 616 } | |
| 617 | |
| 618 #define TEST_FUNCTION test_mul | |
| 619 #define TWO_ARGS | |
| 620 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100) | |
| 621 #include "tgeneric.c" | |
| 622 | |
| 623 /* multiplies x by 53-bit approximation of Pi */ | |
| 624 static int | |
| 625 mpfr_mulpi (mpfr_ptr y, mpfr_srcptr x, mp_rnd_t r) | |
| 626 { | |
| 627 mpfr_t z; | |
| 628 int inex; | |
| 629 | |
| 630 mpfr_init2 (z, 53); | |
| 631 mpfr_set_str_binary (z, "11.001001000011111101101010100010001000010110100011")
; | |
| 632 inex = mpfr_mul (y, x, z, r); | |
| 633 mpfr_clear (z); | |
| 634 return inex; | |
| 635 } | |
| 636 | |
| 637 int | |
| 638 main (int argc, char *argv[]) | |
| 639 { | |
| 640 tests_start_mpfr (); | |
| 641 | |
| 642 check_nans (); | |
| 643 check_exact (); | |
| 644 check_float (); | |
| 645 | |
| 646 check53("6.9314718055994530941514e-1", "0.0", GMP_RNDZ, "0.0"); | |
| 647 check53("0.0", "6.9314718055994530941514e-1", GMP_RNDZ, "0.0"); | |
| 648 check_sign(); | |
| 649 check53("-4.165000000e4", "-0.00004801920768307322868063274915", GMP_RNDN, | |
| 650 "2.0"); | |
| 651 check53("2.71331408349172961467e-08", "-6.72658901114033715233e-165", | |
| 652 GMP_RNDZ, "-1.8251348697787782844e-172"); | |
| 653 check53("0.31869277231188065", "0.88642843322303122", GMP_RNDZ, | |
| 654 "2.8249833483992453642e-1"); | |
| 655 check("8.47622108205396074254e-01", "3.24039313247872939883e-01", GMP_RNDU, | |
| 656 28, 45, 2, "0.375"); | |
| 657 check("2.63978122803639081440e-01", "6.8378615379333496093e-1", GMP_RNDN, | |
| 658 34, 23, 31, "0.180504585267044603"); | |
| 659 check("1.0", "0.11835170935876249132", GMP_RNDU, 6, 41, 36, | |
| 660 "0.1183517093595583"); | |
| 661 check53("67108865.0", "134217729.0", GMP_RNDN, "9.007199456067584e15"); | |
| 662 check("1.37399642157394197284e-01", "2.28877275604219221350e-01", GMP_RNDN, | |
| 663 49, 15, 32, "0.0314472340833162888"); | |
| 664 check("4.03160720978664954828e-01", "5.854828e-1" | |
| 665 /*"5.85483042917246621073e-01"*/, GMP_RNDZ, | |
| 666 51, 22, 32, "0.2360436821472831"); | |
| 667 check("3.90798504668055102229e-14", "9.85394674650308388664e-04", GMP_RNDN, | |
| 668 46, 22, 12, "0.385027296503914762e-16"); | |
| 669 check("4.58687081072827851358e-01", "2.20543551472118792844e-01", GMP_RNDN, | |
| 670 49, 3, 2, "0.09375"); | |
| 671 check_max(); | |
| 672 check_min(); | |
| 673 | |
| 674 check_regression (); | |
| 675 test_generic (2, 500, 100); | |
| 676 | |
| 677 data_check ("data/mulpi", mpfr_mulpi, "mpfr_mulpi"); | |
| 678 | |
| 679 tests_end_mpfr (); | |
| 680 return 0; | |
| 681 } | |
| OLD | NEW |