diff options
author | demengeo <demengeo@280ebfd0-de03-0410-8827-d642c229c3f4> | 2011-02-09 17:34:50 +0000 |
---|---|---|
committer | demengeo <demengeo@280ebfd0-de03-0410-8827-d642c229c3f4> | 2011-02-09 17:34:50 +0000 |
commit | ef317121661004021026d186b3d1604b715d28f2 (patch) | |
tree | 49ea7b1dda19b75cff97e1004761fc2e9f96f618 /tests/tgmpop.c | |
parent | 06f792151f80bd77aff32929459b489711052b1d (diff) | |
download | mpfr-ef317121661004021026d186b3d1604b715d28f2.tar.gz |
Added mpfr_z_sub (function/test/doc)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@7457 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'tests/tgmpop.c')
-rw-r--r-- | tests/tgmpop.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/tests/tgmpop.c b/tests/tgmpop.c index ef6809c8d..c8d234935 100644 --- a/tests/tgmpop.c +++ b/tests/tgmpop.c @@ -412,6 +412,81 @@ test_specialz (int (*mpfr_func)(mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t), } static void +test_special2z (int (*mpfr_func)(mpfr_ptr, mpz_srcptr, mpfr_srcptr, mpfr_rnd_t), + void (*mpz_func)(mpz_ptr, mpz_srcptr, mpz_srcptr), + const char *op) +{ + mpfr_t x1, x2; + mpz_t z1, z2; + int res; + + mpfr_inits2 (128, x1, x2, (mpfr_ptr) 0); + mpz_init (z1); mpz_init(z2); + mpz_fac_ui (z1, 19); /* 19!+1 fits perfectly in a 128 bits mantissa */ + mpz_add_ui (z1, z1, 1); + mpz_fac_ui (z2, 20); /* 20!+1 fits perfectly in a 128 bits mantissa */ + mpz_add_ui (z2, z2, 1); + + res = mpfr_set_z(x1, z1, MPFR_RNDN); + if (res) + { + printf("Specialz %s: set_z1 error\n", op); + exit(1); + } + mpfr_set_z (x2, z2, MPFR_RNDN); + if (res) + { + printf("Specialz %s: set_z2 error\n", op); + exit(1); + } + + /* (19!+1) * (20!+1) fits in a 128 bits number */ + res = mpfr_func(x1, z1, x2, MPFR_RNDN); + if (res) + { + printf("Specialz %s: wrong inexact flag.\n", op); + exit(1); + } + mpz_func(z1, z1, z2); + res = mpfr_set_z (x2, z1, MPFR_RNDN); + if (res) + { + printf("Specialz %s: set_z2 error\n", op); + exit(1); + } + if (mpfr_cmp(x1, x2)) + { + printf("Specialz %s: results differ.\nx1=", op); + mpfr_print_binary(x1); + printf("\nx2="); + mpfr_print_binary(x2); + printf ("\nZ2="); + mpz_out_str (stdout, 2, z1); + putchar('\n'); + exit(1); + } + + mpz_set_ui (z1, 1); + mpz_set_ui (z2, 0); + mpfr_set_ui (x2, 0, MPFR_RNDN); + res = mpfr_func(x1, z1, x2, MPFR_RNDN); + mpz_func (z1, z1, z2); + mpfr_set_z (x2, z1, MPFR_RNDN); + if (mpfr_cmp(x1, x2)) + { + printf("Specialz %s: results differ(2).\nx1=", op); + mpfr_print_binary(x1); + printf("\nx2="); + mpfr_print_binary(x2); + putchar('\n'); + exit(1); + } + + mpz_clear (z1); mpz_clear(z2); + mpfr_clears (x1, x2, (mpfr_ptr) 0); +} + +static void test_genericz (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N, int (*func)(mpfr_ptr, mpfr_srcptr, mpz_srcptr, mpfr_rnd_t), const char *op) @@ -489,6 +564,83 @@ test_genericz (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N, } static void +test_generic2z (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N, + int (*func)(mpfr_ptr, mpz_srcptr, mpfr_srcptr, mpfr_rnd_t), + const char *op) +{ + mpfr_prec_t prec; + mpfr_t arg1, dst_big, dst_small, tmp; + mpz_t arg2; + mpfr_rnd_t rnd; + int inexact, compare, compare2; + unsigned int n; + + mpfr_inits (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0); + mpz_init (arg2); + + for (prec = p0; prec <= p1; prec++) + { + mpfr_set_prec (arg1, prec); + mpfr_set_prec (tmp, prec); + mpfr_set_prec (dst_small, prec); + + for (n=0; n<N; n++) + { + mpfr_urandomb (arg1, RANDS); + mpz_urandomb (arg2, RANDS, 1024); + rnd = RND_RAND (); + mpfr_set_prec (dst_big, 2*prec); + compare = func(dst_big, arg2, arg1, rnd); + if (mpfr_can_round (dst_big, 2*prec, rnd, rnd, prec)) + { + mpfr_set (tmp, dst_big, rnd); + inexact = func(dst_small, arg2, arg1, rnd); + if (mpfr_cmp (tmp, dst_small)) + { + printf ("Results differ for prec=%u rnd_mode=%s and %s_z:\n" + "arg1=", + (unsigned) prec, mpfr_print_rnd_mode (rnd), op); + mpfr_print_binary (arg1); + printf("\narg2="); + mpz_out_str (stdout, 10, arg2); + printf ("\ngot "); + mpfr_dump (dst_small); + printf ("expected "); + mpfr_dump (tmp); + printf ("approx "); + mpfr_dump (dst_big); + exit (1); + } + compare2 = mpfr_cmp (tmp, dst_big); + /* if rounding to nearest, cannot know the sign of t - f(x) + because of composed rounding: y = o(f(x)) and t = o(y) */ + if (compare * compare2 >= 0) + compare = compare + compare2; + else + compare = inexact; /* cannot determine sign(t-f(x)) */ + if (((inexact == 0) && (compare != 0)) || + ((inexact > 0) && (compare <= 0)) || + ((inexact < 0) && (compare >= 0))) + { + printf ("Wrong inexact flag for rnd=%s and %s_z:\n" + "expected %d, got %d\n", + mpfr_print_rnd_mode (rnd), op, compare, inexact); + printf ("\narg1="); mpfr_print_binary (arg1); + printf ("\narg2="); mpz_out_str(stdout, 2, arg2); + printf ("\ndstl="); mpfr_print_binary (dst_big); + printf ("\ndsts="); mpfr_print_binary (dst_small); + printf ("\ntmp ="); mpfr_dump (tmp); + exit (1); + } + } + } + } + + mpz_clear (arg2); + mpfr_clears (arg1, dst_big, dst_small, tmp, (mpfr_ptr) 0); +} + +static void test_genericq (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N, int (*func)(mpfr_ptr, mpfr_srcptr, mpq_srcptr, mpfr_rnd_t), const char *op) @@ -969,6 +1121,8 @@ main (int argc, char *argv[]) test_genericz (2, 100, 100, mpfr_sub_z, "sub"); test_genericz (2, 100, 100, mpfr_mul_z, "mul"); test_genericz (2, 100, 100, mpfr_div_z, "div"); + test_special2z (mpfr_z_sub, mpz_sub, "sub"); + test_generic2z (2, 100, 100, mpfr_z_sub, "sub"); test_genericq (2, 100, 100, mpfr_add_q, "add"); test_genericq (2, 100, 100, mpfr_sub_q, "sub"); |