summaryrefslogtreecommitdiff
path: root/tests/tdiv.c
diff options
context:
space:
mode:
authorthevenyp <thevenyp@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2008-10-17 14:50:27 +0000
committerthevenyp <thevenyp@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2008-10-17 14:50:27 +0000
commitd5a3ca63260b399f31fb5e4b40b8ea542e1d6c94 (patch)
treefdfe342392f733c02852de04737c9281cf9c1967 /tests/tdiv.c
parentd9b9bbac92266eb7fe10f6bd8348ad318a68a980 (diff)
downloadmpc-d5a3ca63260b399f31fb5e4b40b8ea542e1d6c94.tar.gz
tests/tgeneric_ccc.c, tests/tgeneric_ccs.c, tests/tgeneric_ccu.c, tests/tgeneric_cc.c, tests/tgeneric_cfc.c, tests/tgeneric_cuuc.c, tests/tgeneric_fc.c, tests/tgeneric_ccf.c, tests/tgeneric_cuc.c: code moved into test/tgeneric.c.
tests/read_data_cc.c: code moved into tests/read_data.c. tests/mpc-tests.h: helper test function are in this new library tests/tgeneric.c: generic are reuse tests for all function prototypes used in MPC. tests/read_data.c: read data in a file. tests/comparisons.c: comparaison function working also with special values tests/random.c: functions become public tests/tsub_ui.c: use new libmpc-tests tests/tconj.c: use new libmpc-tests tests/tmul_ui.c: use new libmpc-tests tests/tmul_2exp.c: use new libmpc-tests tests/texp.c: use new libmpc-tests tests/tsinh.c: use new libmpc-tests tests/tneg.c: use new libmpc-tests tests/tui_div.c: use new libmpc-tests tests/tsub_fr.c: use new libmpc-tests tests/tdiv_2exp.c: use new libmpc-tests tests/tmul_fr.c: use new libmpc-tests tests/tadd_ui.c: use new libmpc-tests tests/tsqrt.c: use new libmpc-tests tests/ttanh.c: use new libmpc-tests tests/tfr_div.c: use new libmpc-tests tests/tnorm.c: use new libmpc-tests tests/tadd_fr.c: use new libmpc-tests tests/tfr_sub.c: use new libmpc-tests tests/tui_ui_sub.c: use new libmpc-tests tests/tmul_si.c: use new libmpc-tests tests/tdiv_ui.c: use new libmpc-tests tests/tlog.c: use new libmpc-tests tests/tdiv.c: use new libmpc-tests tests/ttan.c: use new libmpc-tests tests/tcos.c: use new libmpc-tests tests/tadd.c: use new libmpc-tests tests/tsin.c: use new libmpc-tests tests/tsub.c: use new libmpc-tests tests/tcosh.c: use new libmpc-tests tests/tmul.c: use new libmpc-tests tests/tabs.c: use new libmpc-tests tests/tsqr.c: use new libmpc-tests tests/tdiv_fr.c: use new libmpc-tests tests/tui_sub.c: removed because mpc_ui_sub is a macro. tests/abs.dat: new test file for mpc_abs. tests/Makefile.am: record previous changes. git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@258 211d60ee-9f03-0410-a15a-8952a2c7a4e4
Diffstat (limited to 'tests/tdiv.c')
-rw-r--r--tests/tdiv.c219
1 files changed, 4 insertions, 215 deletions
diff --git a/tests/tdiv.c b/tests/tdiv.c
index 0ca4cfe..39e094f 100644
--- a/tests/tdiv.c
+++ b/tests/tdiv.c
@@ -19,223 +19,10 @@ along with the MPC Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
-#include <stdio.h>
#include <stdlib.h>
-#include "gmp.h"
-#include "mpfr.h"
-#include "mpc.h"
+#include "mpc-tests.h"
#include "mpc-impl.h"
-static int
-mpc_div_ref (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t);
-
-#include "random.c"
-#define TEST_FUNCTION mpc_div
-#define REFERENCE_FUNCTION mpc_div_ref
-#include "tgeneric_ccc.c"
-
-static int
-mpc_div_ref (mpc_ptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
-{
- int ok = 0, inexact_q, inex_re, inex_im = 0, cancel = 0, sgn;
- mpfr_t u, v, q, t;
- mp_prec_t prec, err;
- mp_rnd_t rnd_re, rnd_im;
-
- if (mpfr_cmp_ui (MPC_IM(c), 0) == 0) /* c is real */
- {
- /* compute imaginary part first in case a=b or a=c */
- inex_im = mpfr_div (MPC_IM(a), MPC_IM(b), MPC_RE(c), MPC_RND_IM(rnd));
- inex_re = mpfr_div (MPC_RE(a), MPC_RE(b), MPC_RE(c), MPC_RND_RE(rnd));
- return MPC_INEX(inex_re, inex_im);
- }
-
- prec = MPC_MAX_PREC(a);
-
- /* try to guess the signs of the real and imaginary parts */
- sgn = mpfr_sgn (MPC_RE(b)) * mpfr_sgn (MPC_RE(c))
- + mpfr_sgn (MPC_IM(b)) * mpfr_sgn (MPC_IM(c));
- rnd_re = (sgn > 0) ? GMP_RNDU : GMP_RNDD;
- sgn = mpfr_sgn (MPC_RE(b)) * mpfr_sgn (MPC_IM(c))
- - mpfr_sgn (MPC_IM(b)) * mpfr_sgn (MPC_RE(c));
- rnd_im = (sgn > 0) ? GMP_RNDU : GMP_RNDD;
-
- /* first try with only one real division */
- prec += mpc_ceil_log2 (prec) + 3;
-
- mpfr_init2 (u, prec);
- mpfr_init2 (v, prec);
- mpfr_init2 (q, prec);
- mpfr_init2 (t, prec);
-
- /* first compute 1/norm(c)^2 rounded away */
- inexact_q = mpfr_mul (u, MPC_RE(c), MPC_RE(c), GMP_RNDZ);
- inexact_q |= mpfr_mul (v, MPC_IM(c), MPC_IM(c), GMP_RNDZ);
- inexact_q |= mpfr_add (q, u, v, GMP_RNDZ); /* 3 ulps */
- inexact_q |= mpfr_ui_div (q, 1, q, GMP_RNDU); /* 7 ulps */
-
- /* now compute b*conjugate(c) */
-
- /* real part */
- inex_re = mpfr_mul (u, MPC_RE(b), MPC_RE(c), rnd_re); /* 1 */
- inex_re |= mpfr_mul (v, MPC_IM(b), MPC_IM(c), rnd_re); /* 1 */
- inex_re |= mpfr_add (t, u, v, rnd_re);
- if (MPFR_IS_ZERO(u))
- {
- if (MPFR_IS_ZERO(v))
- cancel = 0;
- else
- cancel = MPFR_EXP(v) - MPFR_EXP(t);
- }
- else if (MPFR_IS_ZERO(v))
- cancel = MPFR_EXP(u) - MPFR_EXP(t);
- else
- {
- cancel = (MPFR_IS_ZERO(t)) ? (mp_exp_t) prec
- : MAX(MPFR_EXP(u), MPFR_EXP(v)) - MPFR_EXP(t);
- }
- /* err(t) <= [1 + 2*2^cancel] ulp(t) */
- inex_re |= mpfr_mul (t, t, q, rnd_re) || inexact_q;
- /* err(t) <= [1 + 3*(1 + 2*2^cancel) + 14] ulp(t) */
- err = (cancel <= 1) ? 5 : ((cancel == 2) ? 6 :
- ((cancel <= 4) ? 7 : cancel + 3));
- ok = (inex_re == 0)
- || ((err < prec) && mpfr_can_round (t, prec - err, rnd_re,
- MPC_RND_RE (rnd),
- MPFR_PREC (MPC_RE (a))));
- if ((rnd_re == GMP_RNDU && mpfr_sgn (t) < 0)
- || (rnd_re == GMP_RNDD && mpfr_sgn (t) > 0))
- {
- ok = 0;
- rnd_re = INV_RND(rnd_re);
- }
-
- if (ok) /* compute imaginary part */
- {
- inex_im = mpfr_mul (u, MPC_RE(b), MPC_IM(c), INV_RND(rnd_im));
- inex_im |= mpfr_mul (v, MPC_IM(b), MPC_RE(c), rnd_im);
- if (MPFR_IS_ZERO(u))
- {
- if (MPFR_IS_ZERO(v))
- cancel = 0;
- else
- cancel = MPFR_EXP(v);
- }
- else if (MPFR_IS_ZERO(v))
- cancel = MPFR_EXP(u);
- else
- cancel = MAX(MPFR_EXP(u), MPFR_EXP(v));
- inex_im |= mpfr_sub (u, v, u, rnd_im);
- if (!MPFR_IS_ZERO(u))
- cancel = cancel - MPFR_EXP(u);
- inex_im |= mpfr_mul (u, u, q, rnd_im) || inexact_q;
- err = (cancel <= 1) ? 5 : ((cancel == 2) ? 6 :
- ((cancel <= 4) ? 7 : cancel + 3));
- ok = (inex_im == 0)
- || ((err < prec) && mpfr_can_round (u, prec - err, rnd_im,
- MPC_RND_IM (rnd),
- MPFR_PREC (MPC_IM (a))));
- if ((rnd_im == GMP_RNDU && mpfr_sgn (u) < 0)
- || (rnd_im == GMP_RNDD && mpfr_sgn (u) > 0))
- {
- ok = 0;
- rnd_im = INV_RND(rnd_im);
- }
- }
-
- /* now loop with two real divisions, to detect exact quotients */
- while (ok == 0)
- {
- prec += mpc_ceil_log2 (prec) + 3;
-
- mpfr_set_prec (u, prec);
- mpfr_set_prec (v, prec);
- mpfr_set_prec (q, prec);
- mpfr_set_prec (t, prec);
-
- /* first compute norm(c)^2 rounded towards zero */
- inexact_q = mpfr_mul (u, MPC_RE(c), MPC_RE(c), GMP_RNDZ);
- inexact_q |= mpfr_mul (v, MPC_IM(c), MPC_IM(c), GMP_RNDZ);
- inexact_q |= mpfr_add (q, u, v, GMP_RNDZ); /* 3 ulps */
-
- /* now compute b*conjugate(c) */
-
- /* real part */
- inex_re = mpfr_mul (u, MPC_RE(b), MPC_RE(c), rnd_re); /* 1 */
- inex_re |= mpfr_mul (v, MPC_IM(b), MPC_IM(c), rnd_re); /* 1 */
- inex_re |= mpfr_add (t, u, v, rnd_re);
- if (MPFR_IS_ZERO(u))
- {
- if (MPFR_IS_ZERO(v))
- cancel = 0;
- else
- cancel = MPFR_EXP(v) - MPFR_EXP(t);
- }
- else if (MPFR_IS_ZERO(v))
- cancel = MPFR_EXP(u) - MPFR_EXP(t);
- else
- cancel = (MPFR_IS_ZERO(t)) ? (mp_exp_t) prec
- : MAX(MPFR_EXP(u), MPFR_EXP(v)) - MPFR_EXP(t);
- /* err(t) <= [1 + 2*2^cancel] ulp(t) */
- inex_re |= mpfr_div (t, t, q, rnd_re) || inexact_q;
- /* err(t) <= [1 + 2*(1 + 2*2^cancel) + 6] ulp(t) */
- err = (cancel <= 0) ? 4 : cancel + 3; /* FIXME: cancel + 4 ? */
- ok = (inex_re == 0)
- || ((err < prec) && mpfr_can_round (t, prec - err, rnd_re,
- MPC_RND_RE (rnd),
- MPFR_PREC (MPC_RE (a))));
- if ((rnd_re == GMP_RNDU && mpfr_sgn (t) < 0)
- || (rnd_re == GMP_RNDD && mpfr_sgn (t) > 0))
- {
- ok = 0;
- rnd_re = INV_RND(rnd_re);
- }
-
- if (ok) /* compute imaginary part */
- {
- inex_im = mpfr_mul (u, MPC_RE(b), MPC_IM(c), INV_RND(rnd_im));
- inex_im |= mpfr_mul (v, MPC_IM(b), MPC_RE(c), rnd_im);
- if (MPFR_IS_ZERO(u))
- {
- if (MPFR_IS_ZERO(v))
- cancel = 0;
- else
- cancel = MPFR_EXP(v);
- }
- else if (MPFR_IS_ZERO(v))
- cancel = MPFR_EXP(u);
- else
- cancel = MAX(MPFR_EXP(u), MPFR_EXP(v));
- inex_im |= mpfr_sub (u, v, u, rnd_im);
- if (!MPFR_IS_ZERO(u))
- cancel = cancel - MPFR_EXP(u);
- inex_im |= mpfr_div (u, u, q, rnd_im) || inexact_q;
- err = (cancel <= 0) ? 4 : cancel + 3;
- ok = (inex_im == 0)
- || ((err < prec) && mpfr_can_round (u, prec - err, rnd_im,
- MPC_RND_IM (rnd),
- MPFR_PREC (MPC_IM (a))));
-
- if ((rnd_im == GMP_RNDU && mpfr_sgn (u) < 0)
- || (rnd_im == GMP_RNDD && mpfr_sgn (u) > 0))
- {
- ok = 0;
- rnd_im = INV_RND(rnd_im);
- }
- }
- }
-
- inex_re = mpfr_set (MPC_RE(a), t, MPC_RND_RE(rnd)) || inex_re;
- inex_im = mpfr_set (MPC_IM(a), u, MPC_RND_IM(rnd)) || inex_im;
-
- mpfr_clear (u);
- mpfr_clear (v);
- mpfr_clear (q);
- mpfr_clear (t);
-
- return MPC_INEX(inex_re, inex_im);
-}
-
static void
check_regular (void)
{
@@ -317,10 +104,12 @@ check_regular (void)
int
main (void)
{
+ DECL_CCC_FUNC (f, mpc_div);
+
test_start ();
check_regular ();
- tgeneric (2, 1024, 7, 4096);
+ tgeneric (f, 2, 1024, 7, 4096);
test_end ();
return 0;