diff options
Diffstat (limited to 'tests/tmul.c')
-rw-r--r-- | tests/tmul.c | 697 |
1 files changed, 697 insertions, 0 deletions
diff --git a/tests/tmul.c b/tests/tmul.c new file mode 100644 index 0000000..fa5f158 --- /dev/null +++ b/tests/tmul.c @@ -0,0 +1,697 @@ +/* Test file for mpfr_mul. + +Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. +Contributed by the AriC and Caramel projects, INRIA. + +This file is part of the GNU MPFR Library. + +The GNU MPFR Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +The GNU MPFR Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see +http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include <stdio.h> +#include <stdlib.h> + +#include "mpfr-test.h" + +#ifdef CHECK_EXTERNAL +static int +test_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode) +{ + int res; + int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c); + if (ok) + { + mpfr_print_raw (b); + printf (" "); + mpfr_print_raw (c); + } + res = mpfr_mul (a, b, c, rnd_mode); + if (ok) + { + printf (" "); + mpfr_print_raw (a); + printf ("\n"); + } + return res; +} +#else +#define test_mul mpfr_mul +#endif + +/* checks that xs * ys gives the expected result res */ +static void +check (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, + unsigned int px, unsigned int py, unsigned int pz, const char *res) +{ + mpfr_t xx, yy, zz; + + mpfr_init2 (xx, px); + mpfr_init2 (yy, py); + mpfr_init2 (zz, pz); + mpfr_set_str1 (xx, xs); + mpfr_set_str1 (yy, ys); + test_mul(zz, xx, yy, rnd_mode); + if (mpfr_cmp_str1 (zz, res) ) + { + printf ("(1)mpfr_mul failed for x=%s y=%s with rnd=%s\n", + xs, ys, mpfr_print_rnd_mode (rnd_mode)); + printf ("correct is %s, mpfr_mul gives ", res); + mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN); + /* + printf("\nBinary forms:\nxx="); + mpfr_print_binary (xx); + printf("\nyy="); + mpfr_print_binary (yy); + printf("\nzz="); + mpfr_print_binary(zz); + printf("\nre="); + mpfr_set_str1 (zz, res); + mpfr_print_binary(zz); + putchar('\n');*/ + exit (1); + } + mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz); +} + +static void +check53 (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, const char *zs) +{ + mpfr_t xx, yy, zz; + + mpfr_inits2 (53, xx, yy, zz, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); + mpfr_set_str1 (yy, ys); + test_mul (zz, xx, yy, rnd_mode); + if (mpfr_cmp_str1 (zz, zs) ) + { + printf ("(2) mpfr_mul failed for x=%s y=%s with rnd=%s\n", + xs, ys, mpfr_print_rnd_mode(rnd_mode)); + printf ("correct result is %s,\n mpfr_mul gives ", zs); + mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN); + /* + printf("\nBinary forms:\nxx="); + mpfr_print_binary (xx); + printf("\nyy="); + mpfr_print_binary (yy); + printf("\nzz="); + mpfr_print_binary(zz); + printf("\nre="); + mpfr_set_str1 (zz, zs); + mpfr_print_binary(zz); + putchar('\n'); */ + exit (1); + } + mpfr_clears (xx, yy, zz, (mpfr_ptr) 0); +} + +/* checks that x*y gives the right result with 24 bits of precision */ +static void +check24 (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, const char *zs) +{ + mpfr_t xx, yy, zz; + + mpfr_inits2 (24, xx, yy, zz, (mpfr_ptr) 0); + mpfr_set_str1 (xx, xs); + mpfr_set_str1 (yy, ys); + test_mul (zz, xx, yy, rnd_mode); + if (mpfr_cmp_str1 (zz, zs) ) + { + printf ("(3) mpfr_mul failed for x=%s y=%s with " + "rnd=%s\n", xs, ys, mpfr_print_rnd_mode(rnd_mode)); + printf ("correct result is gives %s, mpfr_mul gives ", zs); + mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN); + putchar('\n'); + exit (1); + } + mpfr_clears (xx, yy, zz, (mpfr_ptr) 0); +} + +/* the following examples come from the paper "Number-theoretic Test + Generation for Directed Rounding" from Michael Parks, Table 1 */ +static void +check_float (void) +{ + check24("8388609.0", "8388609.0", MPFR_RNDN, "70368760954880.0"); + check24("16777213.0", "8388609.0", MPFR_RNDN, "140737479966720.0"); + check24("8388611.0", "8388609.0", MPFR_RNDN, "70368777732096.0"); + check24("12582911.0", "8388610.0", MPFR_RNDN, "105553133043712.0"); + check24("12582914.0", "8388610.0", MPFR_RNDN, "105553158209536.0"); + check24("13981013.0", "8388611.0", MPFR_RNDN, "117281279442944.0"); + check24("11184811.0", "8388611.0", MPFR_RNDN, "93825028587520.0"); + check24("11184810.0", "8388611.0", MPFR_RNDN, "93825020198912.0"); + check24("13981014.0", "8388611.0", MPFR_RNDN, "117281287831552.0"); + + check24("8388609.0", "8388609.0", MPFR_RNDZ, "70368760954880.0"); + check24("16777213.0", "8388609.0", MPFR_RNDZ, "140737471578112.0"); + check24("8388611.0", "8388609.0", MPFR_RNDZ, "70368777732096.0"); + check24("12582911.0", "8388610.0", MPFR_RNDZ, "105553124655104.0"); + check24("12582914.0", "8388610.0", MPFR_RNDZ, "105553158209536.0"); + check24("13981013.0", "8388611.0", MPFR_RNDZ, "117281271054336.0"); + check24("11184811.0", "8388611.0", MPFR_RNDZ, "93825028587520.0"); + check24("11184810.0", "8388611.0", MPFR_RNDZ, "93825011810304.0"); + check24("13981014.0", "8388611.0", MPFR_RNDZ, "117281287831552.0"); + + check24("8388609.0", "8388609.0", MPFR_RNDU, "70368769343488.0"); + check24("16777213.0", "8388609.0", MPFR_RNDU, "140737479966720.0"); + check24("8388611.0", "8388609.0", MPFR_RNDU, "70368786120704.0"); + check24("12582911.0", "8388610.0", MPFR_RNDU, "105553133043712.0"); + check24("12582914.0", "8388610.0", MPFR_RNDU, "105553166598144.0"); + check24("13981013.0", "8388611.0", MPFR_RNDU, "117281279442944.0"); + check24("11184811.0", "8388611.0", MPFR_RNDU, "93825036976128.0"); + check24("11184810.0", "8388611.0", MPFR_RNDU, "93825020198912.0"); + check24("13981014.0", "8388611.0", MPFR_RNDU, "117281296220160.0"); + + check24("8388609.0", "8388609.0", MPFR_RNDD, "70368760954880.0"); + check24("16777213.0", "8388609.0", MPFR_RNDD, "140737471578112.0"); + check24("8388611.0", "8388609.0", MPFR_RNDD, "70368777732096.0"); + check24("12582911.0", "8388610.0", MPFR_RNDD, "105553124655104.0"); + check24("12582914.0", "8388610.0", MPFR_RNDD, "105553158209536.0"); + check24("13981013.0", "8388611.0", MPFR_RNDD, "117281271054336.0"); + check24("11184811.0", "8388611.0", MPFR_RNDD, "93825028587520.0"); + check24("11184810.0", "8388611.0", MPFR_RNDD, "93825011810304.0"); + check24("13981014.0", "8388611.0", MPFR_RNDD, "117281287831552.0"); +} + +/* check sign of result */ +static void +check_sign (void) +{ + mpfr_t a, b; + + mpfr_init2 (a, 53); + mpfr_init2 (b, 53); + mpfr_set_si (a, -1, MPFR_RNDN); + mpfr_set_ui (b, 2, MPFR_RNDN); + test_mul(a, b, b, MPFR_RNDN); + if (mpfr_cmp_ui (a, 4) ) + { + printf ("2.0*2.0 gives \n"); + mpfr_out_str(stdout, 10, 0, a, MPFR_RNDN); + putchar('\n'); + exit (1); + } + mpfr_clear(a); mpfr_clear(b); +} + +/* checks that the inexact return value is correct */ +static void +check_exact (void) +{ + mpfr_t a, b, c, d; + mpfr_prec_t prec; + int i, inexact; + mpfr_rnd_t rnd; + + mpfr_init (a); + mpfr_init (b); + mpfr_init (c); + mpfr_init (d); + + mpfr_set_prec (a, 17); + mpfr_set_prec (b, 17); + mpfr_set_prec (c, 32); + mpfr_set_str_binary (a, "1.1000111011000100e-1"); + mpfr_set_str_binary (b, "1.0010001111100111e-1"); + if (test_mul (c, a, b, MPFR_RNDZ)) + { + printf ("wrong return value (1)\n"); + exit (1); + } + + for (prec = 2; prec < 100; prec++) + { + mpfr_set_prec (a, prec); + mpfr_set_prec (b, prec); + mpfr_set_prec (c, 2 * prec - 2); + mpfr_set_prec (d, 2 * prec); + for (i = 0; i < 1000; i++) + { + mpfr_urandomb (a, RANDS); + mpfr_urandomb (b, RANDS); + rnd = RND_RAND (); + inexact = test_mul (c, a, b, rnd); + if (test_mul (d, a, b, rnd)) /* should be always exact */ + { + printf ("unexpected inexact return value\n"); + exit (1); + } + if ((inexact == 0) && mpfr_cmp (c, d)) + { + printf ("inexact=0 but results differ\n"); + exit (1); + } + else if (inexact && (mpfr_cmp (c, d) == 0)) + { + printf ("inexact!=0 but results agree\n"); + printf ("prec=%u rnd=%s a=", (unsigned int) prec, + mpfr_print_rnd_mode (rnd)); + mpfr_out_str (stdout, 2, 0, a, rnd); + printf ("\nb="); + mpfr_out_str (stdout, 2, 0, b, rnd); + printf ("\nc="); + mpfr_out_str (stdout, 2, 0, c, rnd); + printf ("\nd="); + mpfr_out_str (stdout, 2, 0, d, rnd); + printf ("\n"); + exit (1); + } + } + } + + mpfr_clear (a); + mpfr_clear (b); + mpfr_clear (c); + mpfr_clear (d); +} + +static void +check_max(void) +{ + mpfr_t xx, yy, zz; + mpfr_exp_t emin; + + mpfr_init2(xx, 4); + mpfr_init2(yy, 4); + mpfr_init2(zz, 4); + mpfr_set_str1 (xx, "0.68750"); + mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT/2, MPFR_RNDN); + mpfr_set_str1 (yy, "0.68750"); + mpfr_mul_2si(yy, yy, MPFR_EMAX_DEFAULT - MPFR_EMAX_DEFAULT/2 + 1, MPFR_RNDN); + mpfr_clear_flags(); + test_mul(zz, xx, yy, MPFR_RNDU); + if (!(mpfr_overflow_p() && MPFR_IS_INF(zz))) + { + printf("check_max failed (should be an overflow)\n"); + exit(1); + } + + mpfr_clear_flags(); + test_mul(zz, xx, yy, MPFR_RNDD); + if (mpfr_overflow_p() || MPFR_IS_INF(zz)) + { + printf("check_max failed (should NOT be an overflow)\n"); + exit(1); + } + mpfr_set_str1 (xx, "0.93750"); + mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT, MPFR_RNDN); + if (!(MPFR_IS_FP(xx) && MPFR_IS_FP(zz))) + { + printf("check_max failed (internal error)\n"); + exit(1); + } + if (mpfr_cmp(xx, zz) != 0) + { + printf("check_max failed: got "); + mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ); + printf(" instead of "); + mpfr_out_str(stdout, 2, 0, xx, MPFR_RNDZ); + printf("\n"); + exit(1); + } + + /* check underflow */ + emin = mpfr_get_emin (); + set_emin (0); + mpfr_set_str_binary (xx, "0.1E0"); + mpfr_set_str_binary (yy, "0.1E0"); + test_mul (zz, xx, yy, MPFR_RNDN); + /* exact result is 0.1E-1, which should round to 0 */ + MPFR_ASSERTN(mpfr_cmp_ui (zz, 0) == 0 && MPFR_IS_POS(zz)); + set_emin (emin); + + /* coverage test for mpfr_powerof2_raw */ + emin = mpfr_get_emin (); + set_emin (0); + mpfr_set_prec (xx, mp_bits_per_limb + 1); + mpfr_set_str_binary (xx, "0.1E0"); + mpfr_nextabove (xx); + mpfr_set_str_binary (yy, "0.1E0"); + test_mul (zz, xx, yy, MPFR_RNDN); + /* exact result is just above 0.1E-1, which should round to minfloat */ + MPFR_ASSERTN(mpfr_cmp (zz, yy) == 0); + set_emin (emin); + + mpfr_clear(xx); + mpfr_clear(yy); + mpfr_clear(zz); +} + +static void +check_min(void) +{ + mpfr_t xx, yy, zz; + + mpfr_init2(xx, 4); + mpfr_init2(yy, 4); + mpfr_init2(zz, 3); + mpfr_set_str1(xx, "0.9375"); + mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT/2, MPFR_RNDN); + mpfr_set_str1(yy, "0.9375"); + mpfr_mul_2si(yy, yy, MPFR_EMIN_DEFAULT - MPFR_EMIN_DEFAULT/2 - 1, MPFR_RNDN); + test_mul(zz, xx, yy, MPFR_RNDD); + if (mpfr_sgn(zz) != 0) + { + printf("check_min failed: got "); + mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ); + printf(" instead of 0\n"); + exit(1); + } + + test_mul(zz, xx, yy, MPFR_RNDU); + mpfr_set_str1 (xx, "0.5"); + mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT, MPFR_RNDN); + if (mpfr_sgn(xx) <= 0) + { + printf("check_min failed (internal error)\n"); + exit(1); + } + if (mpfr_cmp(xx, zz) != 0) + { + printf("check_min failed: got "); + mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ); + printf(" instead of "); + mpfr_out_str(stdout, 2, 0, xx, MPFR_RNDZ); + printf("\n"); + exit(1); + } + + mpfr_clear(xx); + mpfr_clear(yy); + mpfr_clear(zz); +} + +static void +check_nans (void) +{ + mpfr_t p, x, y; + + mpfr_init2 (x, 123L); + mpfr_init2 (y, 123L); + mpfr_init2 (p, 123L); + + /* nan * 0 == nan */ + mpfr_set_nan (x); + mpfr_set_ui (y, 0L, MPFR_RNDN); + test_mul (p, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (p)); + + /* 1 * nan == nan */ + mpfr_set_ui (x, 1L, MPFR_RNDN); + mpfr_set_nan (y); + test_mul (p, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (p)); + + /* 0 * +inf == nan */ + mpfr_set_ui (x, 0L, MPFR_RNDN); + mpfr_set_nan (y); + test_mul (p, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_nan_p (p)); + + /* +1 * +inf == +inf */ + mpfr_set_ui (x, 1L, MPFR_RNDN); + mpfr_set_inf (y, 1); + test_mul (p, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (p)); + MPFR_ASSERTN (mpfr_sgn (p) > 0); + + /* -1 * +inf == -inf */ + mpfr_set_si (x, -1L, MPFR_RNDN); + mpfr_set_inf (y, 1); + test_mul (p, x, y, MPFR_RNDN); + MPFR_ASSERTN (mpfr_inf_p (p)); + MPFR_ASSERTN (mpfr_sgn (p) < 0); + + mpfr_clear (x); + mpfr_clear (y); + mpfr_clear (p); +} + +#define BUFSIZE 1552 + +static void +get_string (char *s, FILE *fp) +{ + int c, n = BUFSIZE; + + while ((c = getc (fp)) != '\n') + { + if (c == EOF) + { + printf ("Error in get_string: end of file\n"); + exit (1); + } + *(unsigned char *)s++ = c; + if (--n == 0) + { + printf ("Error in get_string: buffer is too small\n"); + exit (1); + } + } + *s = '\0'; +} + +static void +check_regression (void) +{ + mpfr_t x, y, z; + int i; + FILE *fp; + char s[BUFSIZE]; + + mpfr_inits2 (6177, x, y, z, (mpfr_ptr) 0); + /* we read long strings from a file since ISO C90 does not support strings of + length > 509 */ + fp = src_fopen ("tmul.dat", "r"); + if (fp == NULL) + { + fprintf (stderr, "Error, cannot open tmul.dat in srcdir\n"); + exit (1); + } + get_string (s, fp); + mpfr_set_str (y, s, 16, MPFR_RNDN); + get_string (s, fp); + mpfr_set_str (z, s, 16, MPFR_RNDN); + i = mpfr_mul (x, y, z, MPFR_RNDN); + get_string (s, fp); + if (mpfr_cmp_str (x, s, 16, MPFR_RNDN) != 0 || i != -1) + { + printf ("Regression test 1 failed (i=%d, expected -1)\nx=", i); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + fclose (fp); + + mpfr_set_prec (x, 606); + mpfr_set_prec (y, 606); + mpfr_set_prec (z, 606); + + mpfr_set_str (y, "-f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f58736564d9e93e62d324@-1", 16, MPFR_RNDN); + mpfr_set_str (z, "-f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f58736564d9e93e62d324@-1", 16, MPFR_RNDN); + i = mpfr_mul (x, y, z, MPFR_RNDU); + mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff25b5df87f00a5953eb0e6cac9b3d27cc5a64c@-1", 16, MPFR_RNDN); + if (mpfr_cmp (x, y) || i <= 0) + { + printf ("Regression test (2) failed! (i=%d - Expected 1)\n", i); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n'); + exit (1); + } + + mpfr_set_prec (x, 184); + mpfr_set_prec (y, 92); + mpfr_set_prec (z, 1023); + + mpfr_set_str (y, "6.9b8c8498882770d8038c3b0@-1", 16, MPFR_RNDN); + mpfr_set_str (z, "7.44e24b986e7fb296f1e936ce749fec3504cbf0d5ba769466b1c9f1578115efd5d29b4c79271191a920a99280c714d3a657ad6e3afbab77ffce9d697e9bb9110e26d676069afcea8b69f1d1541f2365042d80a97c21dcccd8ace4f1bb58b49922003e738e6f37bb82ef653cb2e87f763974e6ae50ae54e7724c38b80653e3289@255", 16, MPFR_RNDN); + i = mpfr_mul (x, y, z, MPFR_RNDU); + mpfr_set_prec (y, 184); + mpfr_set_str (y, "3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255", + 16, MPFR_RNDN); + if (mpfr_cmp (x, y) || i <= 0) + { + printf ("Regression test (4) failed! (i=%d - expected 1)\n", i); + printf ("Ref: 3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255\n" + "Got: "); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 908); + mpfr_set_prec (y, 908); + mpfr_set_prec (z, 908); + mpfr_set_str (y, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42" +"e6e9a327230345ea6@-1", 16, MPFR_RNDN); + mpfr_set_str (z, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42" + "e6e9a327230345ea6@-1", 16, MPFR_RNDN); + i = mpfr_mul (x, y, z, MPFR_RNDU); + mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" +"fffffffffffffffffffffffffffffffffffffffffffffffffffff337d23f07d8de1da5147a85c" +"dd3464e46068bd4d@-1", 16, MPFR_RNDN); + if (mpfr_cmp (x, y) || i <= 0) + { + printf ("Regression test (5) failed! (i=%d - expected 1)\n", i); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + + mpfr_set_prec (x, 50); + mpfr_set_prec (y, 40); + mpfr_set_prec (z, 53); + mpfr_set_str (y, "4.1ffffffff8", 16, MPFR_RNDN); + mpfr_set_str (z, "4.2000000ffe0000@-4", 16, MPFR_RNDN); + i = mpfr_mul (x, y, z, MPFR_RNDN); + if (mpfr_cmp_str (x, "1.104000041d6c0@-3", 16, MPFR_RNDN) != 0 + || i <= 0) + { + printf ("Regression test (6) failed! (i=%d - expected 1)\nx=", i); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\nMore prec="); + mpfr_set_prec (x, 93); + mpfr_mul (x, y, z, MPFR_RNDN); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 439); + mpfr_set_prec (y, 393); + mpfr_set_str (y, "-1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d" + "4c76273644a29410f31c6809bbdf2a33679a748636600", + 16, MPFR_RNDN); + i = mpfr_mul (x, y, y, MPFR_RNDU); + if (mpfr_cmp_str (x, "2.77a79937c8bbcb495b89b36602306b1c2159a8ff834288a19a08" + "84094f1cda3dc426da61174c4544a173de83c2500f8bfea2e0569e3698", + 16, MPFR_RNDN) != 0 + || i <= 0) + { + printf ("Regression test (7) failed! (i=%d - expected 1)\nx=", i); + mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_set_prec (x, 1023); + mpfr_set_prec (y, 1023); + mpfr_set_prec (z, 511); + mpfr_set_ui (x, 17, MPFR_RNDN); + mpfr_set_ui (y, 42, MPFR_RNDN); + i = mpfr_mul (z, x, y, MPFR_RNDN); + if (mpfr_cmp_ui (z, 17*42) != 0 || i != 0) + { + printf ("Regression test (8) failed! (i=%d - expected 0)\nz=", i); + mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); + printf ("\n"); + exit (1); + } + + mpfr_clears (x, y, z, (mpfr_ptr) 0); +} + +#define TEST_FUNCTION test_mul +#define TWO_ARGS +#define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS) +#include "tgeneric.c" + +/* multiplies x by 53-bit approximation of Pi */ +static int +mpfr_mulpi (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r) +{ + mpfr_t z; + int inex; + + mpfr_init2 (z, 53); + mpfr_set_str_binary (z, "11.001001000011111101101010100010001000010110100011"); + inex = mpfr_mul (y, x, z, r); + mpfr_clear (z); + return inex; +} + +static void +valgrind20110503 (void) +{ + mpfr_t a, b, c; + + mpfr_init2 (a, 2); + mpfr_init2 (b, 2005); + mpfr_init2 (c, 2); + + mpfr_set_ui (b, 5, MPFR_RNDN); + mpfr_nextabove (b); + mpfr_set_ui (c, 1, MPFR_RNDN); + mpfr_mul (a, b, c, MPFR_RNDZ); + /* After the call to mpfr_mulhigh_n, valgrind complains: + Conditional jump or move depends on uninitialised value(s) */ + + mpfr_clears (a, b, c, (mpfr_ptr) 0); +} + +int +main (int argc, char *argv[]) +{ + tests_start_mpfr (); + + check_nans (); + check_exact (); + check_float (); + + check53("6.9314718055994530941514e-1", "0.0", MPFR_RNDZ, "0.0"); + check53("0.0", "6.9314718055994530941514e-1", MPFR_RNDZ, "0.0"); + check_sign(); + check53("-4.165000000e4", "-0.00004801920768307322868063274915", MPFR_RNDN, + "2.0"); + check53("2.71331408349172961467e-08", "-6.72658901114033715233e-165", + MPFR_RNDZ, "-1.8251348697787782844e-172"); + check53("2.71331408349172961467e-08", "-6.72658901114033715233e-165", + MPFR_RNDA, "-1.8251348697787786e-172"); + check53("0.31869277231188065", "0.88642843322303122", MPFR_RNDZ, + "2.8249833483992453642e-1"); + check("8.47622108205396074254e-01", "3.24039313247872939883e-01", MPFR_RNDU, + 28, 45, 2, "0.375"); + check("8.47622108205396074254e-01", "3.24039313247872939883e-01", MPFR_RNDA, + 28, 45, 2, "0.375"); + check("2.63978122803639081440e-01", "6.8378615379333496093e-1", MPFR_RNDN, + 34, 23, 31, "0.180504585267044603"); + check("1.0", "0.11835170935876249132", MPFR_RNDU, 6, 41, 36, + "0.1183517093595583"); + check53("67108865.0", "134217729.0", MPFR_RNDN, "9.007199456067584e15"); + check("1.37399642157394197284e-01", "2.28877275604219221350e-01", MPFR_RNDN, + 49, 15, 32, "0.0314472340833162888"); + check("4.03160720978664954828e-01", "5.854828e-1" + /*"5.85483042917246621073e-01"*/, MPFR_RNDZ, + 51, 22, 32, "0.2360436821472831"); + check("3.90798504668055102229e-14", "9.85394674650308388664e-04", MPFR_RNDN, + 46, 22, 12, "0.385027296503914762e-16"); + check("4.58687081072827851358e-01", "2.20543551472118792844e-01", MPFR_RNDN, + 49, 3, 2, "0.09375"); + check_max(); + check_min(); + + check_regression (); + test_generic (2, 500, 100); + + data_check ("data/mulpi", mpfr_mulpi, "mpfr_mulpi"); + + valgrind20110503 (); + + tests_end_mpfr (); + return 0; +} |