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