summaryrefslogtreecommitdiff
path: root/tests/tgmpop.c
diff options
context:
space:
mode:
authordemengeo <demengeo@280ebfd0-de03-0410-8827-d642c229c3f4>2011-02-09 17:34:50 +0000
committerdemengeo <demengeo@280ebfd0-de03-0410-8827-d642c229c3f4>2011-02-09 17:34:50 +0000
commitef317121661004021026d186b3d1604b715d28f2 (patch)
tree49ea7b1dda19b75cff97e1004761fc2e9f96f618 /tests/tgmpop.c
parent06f792151f80bd77aff32929459b489711052b1d (diff)
downloadmpfr-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.c154
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");