diff options
Diffstat (limited to 'mpc/tests/tgeneric.c')
-rw-r--r-- | mpc/tests/tgeneric.c | 1412 |
1 files changed, 1412 insertions, 0 deletions
diff --git a/mpc/tests/tgeneric.c b/mpc/tests/tgeneric.c new file mode 100644 index 0000000000..a2bb460e74 --- /dev/null +++ b/mpc/tests/tgeneric.c @@ -0,0 +1,1412 @@ +/* tgeneric.c -- File for generic tests. + +Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA + +This file is part of GNU MPC. + +GNU MPC 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. + +GNU MPC 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 this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +/* Warning: unlike the MPFR macro (defined in mpfr-impl.h), this one returns + true when b is singular */ +#define MPFR_CAN_ROUND(b,err,prec,rnd) \ + (mpfr_zero_p (b) || mpfr_inf_p (b) \ + || mpfr_can_round (b, (long)mpfr_get_prec (b) - (err), (rnd), \ + GMP_RNDZ, (prec) + ((rnd)==GMP_RNDN))) + +/* functions with one input, one output */ +static void +tgeneric_cc (mpc_function *function, mpc_ptr op, mpc_ptr rop, + mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) +{ + known_signs_t ks = {1, 1}; + + /* We compute the result with four times the precision and check whether the + rounding is correct. Error reports in this part of the algorithm might + still be wrong, though, since there are two consecutive roundings (but we + try to avoid them). */ + function->pointer.CC (rop4, op, rnd); + function->pointer.CC (rop, op, rnd); + + /* can't use the mpfr_can_round function when argument is singular, + use a custom macro instead. */ + if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), + MPC_RND_RE (rnd)) + && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), + MPC_RND_IM (rnd))) + mpc_set (rop4rnd, rop4, rnd); + else + /* avoid double rounding error */ + return; + + if (same_mpc_value (rop, rop4rnd, ks)) + return; + + /* rounding failed */ + printf ("Rounding in %s might be incorrect for\n", function->name); + MPC_OUT (op); + + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd))); + + printf ("\n%s gives ", function->name); + MPC_OUT (rop); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop4); + printf ("and is rounded to "); + MPC_OUT (rop4rnd); + + exit (1); +} + +static void +tgeneric_cc_c (mpc_function *function, mpc_ptr op, mpc_ptr rop1, mpc_ptr rop2, + mpc_ptr rop14, mpc_ptr rop24, mpc_ptr rop14rnd, mpc_ptr rop24rnd, + mpc_rnd_t rnd1, mpc_rnd_t rnd2) +{ + /* same as the previous function, but for mpc functions computing two + results from one argument */ + known_signs_t ks = {1, 1}; + + function->pointer.CC_C (rop14, rop24, op, rnd1, rnd2); + function->pointer.CC_C (rop1, rop2, op, rnd1, rnd2); + + if ( MPFR_CAN_ROUND (mpc_realref (rop14), 1, MPC_PREC_RE (rop1), + MPC_RND_RE (rnd1)) + && MPFR_CAN_ROUND (mpc_imagref (rop14), 1, MPC_PREC_IM (rop1), + MPC_RND_IM (rnd1)) + && MPFR_CAN_ROUND (mpc_realref (rop24), 1, MPC_PREC_RE (rop2), + MPC_RND_RE (rnd2)) + && MPFR_CAN_ROUND (mpc_imagref (rop24), 1, MPC_PREC_IM (rop2), + MPC_RND_IM (rnd2))) { + mpc_set (rop14rnd, rop14, rnd1); + mpc_set (rop24rnd, rop24, rnd2); + } + else + return; + + if (!same_mpc_value (rop1, rop14rnd, ks)) { + /* rounding failed for first result */ + printf ("Rounding might be incorrect for the first result of %s at\n", function->name); + MPC_OUT (op); + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd1)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd1))); + printf ("\n%s gives ", function->name); + MPC_OUT (rop1); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop14); + printf ("and is rounded to "); + MPC_OUT (rop14rnd); + exit (1); + } + else if (!same_mpc_value (rop2, rop24rnd, ks)) { + /* rounding failed for second result */ + printf ("Rounding might be incorrect for the second result of %s at\n", function->name); + MPC_OUT (op); + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd2)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd2))); + printf ("\n%s gives ", function->name); + MPC_OUT (rop2); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop24); + printf ("and is rounded to "); + MPC_OUT (rop24rnd); + exit (1); + } +} + +static void +tgeneric_fc (mpc_function *function, mpc_ptr op, mpfr_ptr rop, + mpfr_ptr rop4, mpfr_ptr rop4rnd, mpfr_rnd_t rnd) +{ + function->pointer.FC (rop4, op, rnd); + function->pointer.FC (rop, op, rnd); + if (MPFR_CAN_ROUND (rop4, 1, mpfr_get_prec (rop), rnd)) + mpfr_set (rop4rnd, rop4, rnd); + else + return; + + if (same_mpfr_value (rop, rop4rnd, 1)) + return; + + printf ("Rounding in %s might be incorrect for\n", function->name); + MPC_OUT (op); + printf ("with rounding mode %s", mpfr_print_rnd_mode (rnd)); + + printf ("\n%s gives ", function->name); + MPFR_OUT (rop); + printf ("%s quadruple precision gives ", function->name); + MPFR_OUT (rop4); + printf ("and is rounded to "); + MPFR_OUT (rop4rnd); + + exit (1); +} + +static void +tgeneric_cfc (mpc_function *function, mpfr_ptr op1, mpc_ptr op2, + mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) +{ + known_signs_t ks = {1, 1}; + + function->pointer.CFC (rop4, op1, op2, rnd); + function->pointer.CFC (rop, op1, op2, rnd); + if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), + MPC_RND_RE (rnd)) + && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), + MPC_RND_IM (rnd))) + mpc_set (rop4rnd, rop4, rnd); + else + return; + + if (same_mpc_value (rop, rop4rnd, ks)) + return; + + printf ("Rounding in %s might be incorrect for\n", function->name); + MPFR_OUT (op1); + MPC_OUT (op2); + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd))); + + printf ("\n%s gives ", function->name); + MPC_OUT (rop); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop4); + printf ("and is rounded to "); + MPC_OUT (rop4rnd); + + exit (1); +} + +static void +tgeneric_ccf (mpc_function *function, mpc_ptr op1, mpfr_ptr op2, + mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) +{ + known_signs_t ks = {1, 1}; + + function->pointer.CCF (rop4, op1, op2, rnd); + function->pointer.CCF (rop, op1, op2, rnd); + if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), + MPC_RND_RE (rnd)) + && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), + MPC_RND_IM (rnd))) + mpc_set (rop4rnd, rop4, rnd); + else + return; + + if (same_mpc_value (rop, rop4rnd, ks)) + return; + + printf ("Rounding in %s might be incorrect for\n", function->name); + MPC_OUT (op1); + MPFR_OUT (op2); + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd))); + + printf ("\n%s gives ", function->name); + MPC_OUT (rop); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop4); + printf ("and is rounded to "); + MPC_OUT (rop4rnd); + + exit (1); +} + +/* for functions with one mpc_t output, two mpc_t inputs */ +static void +tgeneric_c_cc (mpc_function *function, mpc_ptr op1, mpc_ptr op2, + mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) +{ + known_signs_t ks = {1, 1}; + + /* We compute the result with four times the precision and check whether the + rounding is correct. Error reports in this part of the algorithm might + still be wrong, though, since there are two consecutive roundings (but we + try to avoid them). */ + function->pointer.C_CC (rop4, op1, op2, rnd); + function->pointer.C_CC (rop, op1, op2, rnd); + + /* can't use mpfr_can_round when argument is singular */ + if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), + MPC_RND_RE (rnd)) + && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), + MPC_RND_IM (rnd))) + mpc_set (rop4rnd, rop4, rnd); + else + /* avoid double rounding error */ + return; + + if (same_mpc_value (rop, rop4rnd, ks)) + return; + + /* rounding failed */ + printf ("Rounding in %s might be incorrect for\n", function->name); + MPC_OUT (op1); + MPC_OUT (op2); + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd))); + + printf ("\n%s gives ", function->name); + MPC_OUT (rop); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop4); + printf ("and is rounded to "); + MPC_OUT (rop4rnd); + + exit (1); +} + +static void +tgeneric_cccc (mpc_function *function, mpc_ptr op1, mpc_ptr op2, mpc_ptr op3, + mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) +{ + known_signs_t ks = {1, 1}; + + /* We compute the result with four times the precision and check whether the + rounding is correct. Error reports in this part of the algorithm might + still be wrong, though, since there are two consecutive roundings (but we + try to avoid them). */ + function->pointer.CCCC (rop4, op1, op2, op3, rnd); + function->pointer.CCCC (rop, op1, op2, op3, rnd); + + /* can't use mpfr_can_round when argument is singular */ + if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), + MPC_RND_RE (rnd)) + && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), + MPC_RND_IM (rnd))) + mpc_set (rop4rnd, rop4, rnd); + else + /* avoid double rounding error */ + return; + + if (same_mpc_value (rop, rop4rnd, ks)) + return; + + /* rounding failed */ + printf ("Rounding in %s might be incorrect for\n", function->name); + MPC_OUT (op1); + MPC_OUT (op2); + MPC_OUT (op3); + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd))); + + printf ("\n%s gives ", function->name); + MPC_OUT (rop); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop4); + printf ("and is rounded to "); + MPC_OUT (rop4rnd); + + exit (1); +} + +static void +tgeneric_ccu (mpc_function *function, mpc_ptr op1, unsigned long int op2, + mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) +{ + known_signs_t ks = {1, 1}; + + function->pointer.CCU (rop4, op1, op2, rnd); + function->pointer.CCU (rop, op1, op2, rnd); + if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), + MPC_RND_RE (rnd)) + && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), + MPC_RND_IM (rnd))) + mpc_set (rop4rnd, rop4, rnd); + else + return; + + if (same_mpc_value (rop, rop4rnd, ks)) + return; + + printf ("Rounding in %s might be incorrect for\n", function->name); + MPC_OUT (op1); + printf ("op2=%lu\n", op2); + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd))); + + printf ("\n%s gives ", function->name); + MPC_OUT (rop); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop4); + printf ("and is rounded to "); + MPC_OUT (rop4rnd); + + exit (1); +} + +static void +tgeneric_cuc (mpc_function *function, unsigned long int op1, mpc_ptr op2, + mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) +{ + known_signs_t ks = {1, 1}; + + function->pointer.CUC (rop4, op1, op2, rnd); + function->pointer.CUC (rop, op1, op2, rnd); + if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), + MPC_RND_RE (rnd)) + && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), + MPC_RND_IM (rnd))) + mpc_set (rop4rnd, rop4, rnd); + else + return; + + if (same_mpc_value (rop, rop4rnd, ks)) + return; + + printf ("Rounding in %s might be incorrect for\n", function->name); + printf ("op1=%lu\n", op1); + MPC_OUT (op2); + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd))); + + printf ("\n%s gives ", function->name); + MPC_OUT (rop); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop4); + printf ("and is rounded to "); + MPC_OUT (rop4rnd); + + exit (1); +} + +static void +tgeneric_ccs (mpc_function *function, mpc_ptr op1, long int op2, + mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) +{ + known_signs_t ks = {1, 1}; + + function->pointer.CCS (rop4, op1, op2, rnd); + function->pointer.CCS (rop, op1, op2, rnd); + if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), + MPC_RND_RE (rnd)) + && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), + MPC_RND_IM (rnd))) + mpc_set (rop4rnd, rop4, rnd); + else + return; + + if (same_mpc_value (rop, rop4rnd, ks)) + return; + + printf ("Rounding in %s might be incorrect for\n", function->name); + MPC_OUT (op1); + printf ("op2=%ld\n", op2); + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd))); + + printf ("\n%s gives ", function->name); + MPC_OUT (rop); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop4); + printf ("and is rounded to "); + MPC_OUT (rop4rnd); + + exit (1); +} + + +static void +tgeneric_cci (mpc_function *function, mpc_ptr op1, int op2, + mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) +{ + known_signs_t ks = {1, 1}; + + function->pointer.CCI (rop4, op1, op2, rnd); + function->pointer.CCI (rop, op1, op2, rnd); + if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), + MPC_RND_RE (rnd)) + && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), + MPC_RND_IM (rnd))) + mpc_set (rop4rnd, rop4, rnd); + else + return; + + if (same_mpc_value (rop, rop4rnd, ks)) + return; + + printf ("Rounding in %s might be incorrect for\n", function->name); + MPC_OUT (op1); + printf ("op2=%d\n", op2); + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd))); + + printf ("\n%s gives ", function->name); + MPC_OUT (rop); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop4); + printf ("and is rounded to "); + MPC_OUT (rop4rnd); + + exit (1); +} + +static void +tgeneric_cuuc (mpc_function *function, unsigned long int op1, + unsigned long int op2, mpc_ptr op3, mpc_ptr rop, + mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) +{ + known_signs_t ks = {1, 1}; + + function->pointer.CUUC (rop4, op1, op2, op3, rnd); + function->pointer.CUUC (rop, op1, op2, op3, rnd); + if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), + MPC_RND_RE (rnd)) + && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), + MPC_RND_IM (rnd))) + mpc_set (rop4rnd, rop4, rnd); + else + return; + + if (same_mpc_value (rop, rop4rnd, ks)) + return; + + printf ("Rounding in %s might be incorrect for\n", function->name); + printf ("op1=%lu\n", op1); + printf ("op2=%lu\n", op2); + MPC_OUT (op3); + printf ("with rounding mode (%s, %s)", + mpfr_print_rnd_mode (MPC_RND_RE (rnd)), + mpfr_print_rnd_mode (MPC_RND_IM (rnd))); + + printf ("\n%s gives ", function->name); + MPC_OUT (rop); + printf ("%s quadruple precision gives ", function->name); + MPC_OUT (rop4); + printf ("and is rounded to "); + MPC_OUT (rop4rnd); + + exit (1); +} + + +/* Test parameter reuse: the function should not use its output parameter in + internal computations. */ +static void +reuse_cc (mpc_function* function, mpc_srcptr z, mpc_ptr got, mpc_ptr expected) +{ + known_signs_t ks = {1, 1}; + + mpc_set (got, z, MPC_RNDNN); /* exact */ + function->pointer.CC (expected, z, MPC_RNDNN); + function->pointer.CC (got, got, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(z, z) for\n", function->name); + MPC_OUT (z); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } +} + +static void +reuse_cc_c (mpc_function* function, mpc_srcptr z, mpc_ptr got1, mpc_ptr got2, + mpc_ptr exp1, mpc_ptr exp2) +{ + known_signs_t ks = {1, 1}; + + function->pointer.CC_C (exp1, exp2, z, MPC_RNDNN, MPC_RNDNN); + mpc_set (got1, z, MPC_RNDNN); /* exact */ + function->pointer.CC_C (got1, got2, got1, MPC_RNDNN, MPC_RNDNN); + if ( !same_mpc_value (got1, exp1, ks) + || !same_mpc_value (got2, exp2, ks)) { + printf ("Reuse error in first result of %s for\n", function->name); + MPC_OUT (z); + MPC_OUT (exp1); + MPC_OUT (got1); + MPC_OUT (exp2); + MPC_OUT (got2); + exit (1); + } + mpc_set (got2, z, MPC_RNDNN); /* exact */ + function->pointer.CC_C (got1, got2, got2, MPC_RNDNN, MPC_RNDNN); + if ( !same_mpc_value (got1, exp1, ks) + || !same_mpc_value (got2, exp2, ks)) { + printf ("Reuse error in second result of %s for\n", function->name); + MPC_OUT (z); + MPC_OUT (exp1); + MPC_OUT (got1); + MPC_OUT (exp2); + MPC_OUT (got2); + exit (1); + } +} + +static void +reuse_fc (mpc_function* function, mpc_ptr z, mpc_ptr x, mpfr_ptr expected) +{ + mpc_set (x, z, MPC_RNDNN); /* exact */ + function->pointer.FC (expected, z, GMP_RNDN); + function->pointer.FC (mpc_realref (x), x, GMP_RNDN); + if (!same_mpfr_value (mpc_realref (x), expected, 1)) + { + mpfr_t got; + got[0] = mpc_realref(x)[0]; /* display sensible name */ + printf ("Reuse error for %s(mpc_realref(z), z) for\n", function->name); + MPC_OUT (z); + MPFR_OUT (expected); + MPFR_OUT (got); + + exit (1); + } + mpc_set (x, z, MPC_RNDNN); /* exact */ + function->pointer.FC (mpc_imagref (x), x, GMP_RNDN); + if (!same_mpfr_value (mpc_imagref (x), expected, 1)) + { + mpfr_t got; + got[0] = mpc_imagref(x)[0]; /* display sensible name */ + printf ("Reuse error for %s(mpc_imagref(z), z) for \n", function->name); + MPC_OUT (z); + MPFR_OUT (expected); + MPFR_OUT (got); + + exit (1); + } +} + +static void +reuse_cfc (mpc_function* function, mpc_srcptr z, mpfr_srcptr x, mpc_ptr got, + mpc_ptr expected) +{ + known_signs_t ks = {1, 1}; + + mpc_set (got, z, MPC_RNDNN); /* exact */ + function->pointer.CFC (expected, x, z, MPC_RNDNN); + function->pointer.CFC (got, x, got, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(z, x, z) for\n", function->name); + MPFR_OUT (x); + MPC_OUT (z); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } +} + +static void +reuse_ccf (mpc_function* function, mpc_srcptr z, mpfr_srcptr x, mpc_ptr got, + mpc_ptr expected) +{ + known_signs_t ks = {1, 1}; + + mpc_set (got, z, MPC_RNDNN); /* exact */ + function->pointer.CCF (expected, z, x, MPC_RNDNN); + function->pointer.CCF (got, got, x, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(z, z, x, RNDNN) for\n", function->name); + MPC_OUT (z); + MPFR_OUT (x); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } +} + +/* for functions with one mpc_t output, two mpc_t inputs */ +static void +reuse_c_cc (mpc_function* function, mpc_srcptr z, mpc_srcptr x, + mpc_ptr got, mpc_ptr expected) +{ + known_signs_t ks = {1, 1}; + + mpc_set (got, z, MPC_RNDNN); /* exact */ + function->pointer.C_CC (expected, z, x, MPC_RNDNN); + function->pointer.C_CC (got, got, x, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(z, z, x) for\n", function->name); + MPC_OUT (z); + MPC_OUT (x); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } + mpc_set (got, x, MPC_RNDNN); /* exact */ + function->pointer.C_CC (expected, z, x, MPC_RNDNN); + function->pointer.C_CC (got, z, got, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(x, z, x) for\n", function->name); + MPC_OUT (z); + MPC_OUT (x); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } + mpc_set (got, x, MPC_RNDNN); /* exact */ + function->pointer.C_CC (expected, x, x, MPC_RNDNN); + function->pointer.C_CC (got, got, got, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(x, x, x) for\n", function->name); + MPC_OUT (x); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } +} + +static void +reuse_cccc (mpc_function* function, mpc_srcptr z, mpc_srcptr x, mpc_srcptr y, + mpc_ptr got, mpc_ptr expected) +{ + known_signs_t ks = {1, 1}; + + mpc_set (got, z, MPC_RNDNN); /* exact */ + function->pointer.CCCC (expected, z, x, y, MPC_RNDNN); + function->pointer.CCCC (got, got, x, y, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(z, z, x, y) for\n", function->name); + MPC_OUT (z); + MPC_OUT (x); + MPC_OUT (y); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } + + mpc_set (got, x, MPC_RNDNN); /* exact */ + function->pointer.CCCC (expected, z, x, y, MPC_RNDNN); + function->pointer.CCCC (got, z, got, y, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(x, z, x, y) for\n", function->name); + MPC_OUT (z); + MPC_OUT (x); + MPC_OUT (y); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } + + mpc_set (got, y, MPC_RNDNN); /* exact */ + function->pointer.CCCC (expected, z, x, y, MPC_RNDNN); + function->pointer.CCCC (got, z, x, got, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(y, z, x, y) for\n", function->name); + MPC_OUT (z); + MPC_OUT (x); + MPC_OUT (y); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } + + mpc_set (got, x, MPC_RNDNN); /* exact */ + function->pointer.CCCC (expected, x, x, x, MPC_RNDNN); + function->pointer.CCCC (got, got, got, got, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(x, x, x, x) for\n", function->name); + MPC_OUT (x); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } +} + +static void +reuse_ccu (mpc_function* function, mpc_srcptr z, unsigned long ul, + mpc_ptr got, mpc_ptr expected) +{ + known_signs_t ks = {1, 1}; + + mpc_set (got, z, MPC_RNDNN); /* exact */ + function->pointer.CCU (expected, z, ul, MPC_RNDNN); + function->pointer.CCU (got, got, ul, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(z, z, n) for\n", function->name); + MPC_OUT (z); + printf ("n=%lu\n", ul); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } +} + +static void +reuse_cuc (mpc_function* function, unsigned long ul, mpc_srcptr z, + mpc_ptr got, mpc_ptr expected) +{ + known_signs_t ks = {1, 1}; + + mpc_set (got, z, MPC_RNDNN); /* exact */ + function->pointer.CUC (expected, ul, z,MPC_RNDNN); + function->pointer.CUC (got, ul, got, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(z, n, z) for\n", function->name); + printf ("n=%lu\n", ul); + MPC_OUT (z); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } +} + +static void +reuse_ccs (mpc_function* function, mpc_srcptr z, long lo, + mpc_ptr got, mpc_ptr expected) +{ + known_signs_t ks = {1, 1}; + + mpc_set (got, z, MPC_RNDNN); /* exact */ + function->pointer.CCS (expected, z, lo, MPC_RNDNN); + function->pointer.CCS (got, got, lo, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(z, z, n) for\n", function->name); + MPC_OUT (z); + printf ("n=%ld\n", lo); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } +} + +static void +reuse_cci (mpc_function* function, mpc_srcptr z, int i, + mpc_ptr got, mpc_ptr expected) +{ + known_signs_t ks = {1, 1}; + + mpc_set (got, z, MPC_RNDNN); /* exact */ + function->pointer.CCI (expected, z, i, MPC_RNDNN); + function->pointer.CCI (got, got, i, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(z, z, n) for\n", function->name); + MPC_OUT (z); + printf ("n=%d\n", i); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } +} + +static void +reuse_cuuc (mpc_function* function, unsigned long ul1, unsigned long ul2, + mpc_srcptr z, mpc_ptr got, mpc_ptr expected) +{ + known_signs_t ks = {1, 1}; + + mpc_set (got, z, MPC_RNDNN); /* exact */ + function->pointer.CUUC (expected, ul1, ul2, z,MPC_RNDNN); + function->pointer.CUUC (got, ul1, ul2, got, MPC_RNDNN); + if (!same_mpc_value (got, expected, ks)) + { + printf ("Reuse error for %s(z, m, n, z) for\n", function->name); + printf ("m=%lu\n", ul1); + printf ("n=%lu\n", ul2); + MPC_OUT (z); + MPC_OUT (expected); + MPC_OUT (got); + + exit (1); + } +} + + +/* helper functions for iterating over mpfr rounding modes */ +static mpfr_rnd_t +first_rnd_mode (void) +{ + return GMP_RNDN; +} + +static mpfr_rnd_t +next_rnd_mode (mpfr_rnd_t curr) + /* assumes that all rounding modes are non-negative, and returns -1 + when curr is the last rounding mode */ +{ + switch (curr) { + case GMP_RNDN: + return GMP_RNDZ; + case GMP_RNDZ: + return GMP_RNDU; + case GMP_RNDU: + return GMP_RNDD; + default: + /* return invalid guard value in mpfr_rnd_t */ +#if MPFR_VERSION_MAJOR < 3 + return GMP_RNDNA; +#else + return MPFR_RNDA; /* valid rounding type, but not (yet) used in mpc */ +#endif + } +} + +static int +is_valid_rnd_mode (mpfr_rnd_t curr) + /* returns 1 if curr is a valid rounding mode, and 0otherwise */ +{ + if ( curr == GMP_RNDN || curr == GMP_RNDZ + || curr == GMP_RNDU || curr == GMP_RNDD) + return 1; + else + return 0; +} + +/* tgeneric(prec_min, prec_max, step, exp_max) checks rounding with random + numbers: + - with precision ranging from prec_min to prec_max with an increment of + step, + - with exponent between -exp_max and exp_max. + + It also checks parameter reuse (it is assumed here that either two mpc_t + variables are equal or they are different, in the sense that the real part + of one of them cannot be the imaginary part of the other). */ +void +tgeneric (mpc_function function, mpfr_prec_t prec_min, + mpfr_prec_t prec_max, mpfr_prec_t step, mpfr_exp_t exp_max) +{ + unsigned long ul1 = 0, ul2 = 0; + long lo = 0; + int i = 0; + mpfr_t x1, x2, xxxx; + mpc_t z1, z2, z3, z4, z5, zzzz, zzzz2; + + mpfr_rnd_t rnd_re, rnd_im, rnd2_re, rnd2_im; + mpfr_prec_t prec; + mpfr_exp_t exp_min; + int special, special_cases; + + mpc_init2 (z1, prec_max); + switch (function.type) + { + case C_CC: + mpc_init2 (z2, prec_max); + mpc_init2 (z3, prec_max); + mpc_init2 (z4, prec_max); + mpc_init2 (zzzz, 4*prec_max); + special_cases = 8; + break; + case CCCC: + mpc_init2 (z2, prec_max); + mpc_init2 (z3, prec_max); + mpc_init2 (z4, prec_max); + mpc_init2 (z5, prec_max); + mpc_init2 (zzzz, 4*prec_max); + special_cases = 8; + break; + case FC: + mpfr_init2 (x1, prec_max); + mpfr_init2 (x2, prec_max); + mpfr_init2 (xxxx, 4*prec_max); + mpc_init2 (z2, prec_max); + special_cases = 4; + break; + case CCF: case CFC: + mpfr_init2 (x1, prec_max); + mpc_init2 (z2, prec_max); + mpc_init2 (z3, prec_max); + mpc_init2 (zzzz, 4*prec_max); + special_cases = 6; + break; + case CCI: case CCS: + case CCU: case CUC: + mpc_init2 (z2, prec_max); + mpc_init2 (z3, prec_max); + mpc_init2 (zzzz, 4*prec_max); + special_cases = 5; + break; + case CUUC: + mpc_init2 (z2, prec_max); + mpc_init2 (z3, prec_max); + mpc_init2 (zzzz, 4*prec_max); + special_cases = 6; + break; + case CC_C: + mpc_init2 (z2, prec_max); + mpc_init2 (z3, prec_max); + mpc_init2 (z4, prec_max); + mpc_init2 (z5, prec_max); + mpc_init2 (zzzz, 4*prec_max); + mpc_init2 (zzzz2, 4*prec_max); + special_cases = 4; + break; + case CC: + default: + mpc_init2 (z2, prec_max); + mpc_init2 (z3, prec_max); + mpc_init2 (zzzz, 4*prec_max); + special_cases = 4; + } + + exp_min = mpfr_get_emin (); + if (exp_max <= 0 || exp_max > mpfr_get_emax ()) + exp_max = mpfr_get_emax(); + if (-exp_max > exp_min) + exp_min = - exp_max; + + if (step < 1) + step = 1; + + for (prec = prec_min, special = 0; + prec <= prec_max || special <= special_cases; + prec+=step, special += (prec > prec_max ? 1 : 0)) { + /* In the end, test functions in special cases of purely real, purely + imaginary or infinite arguments. */ + + /* probability of one zero part in 256th (25 is almost 10%) */ + const unsigned int zero_probability = special != 0 ? 0 : 25; + + mpc_set_prec (z1, prec); + test_default_random (z1, exp_min, exp_max, 128, zero_probability); + + switch (function.type) + { + case C_CC: + mpc_set_prec (z2, prec); + test_default_random (z2, exp_min, exp_max, 128, zero_probability); + mpc_set_prec (z3, prec); + mpc_set_prec (z4, prec); + mpc_set_prec (zzzz, 4*prec); + switch (special) + { + case 1: + mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); + break; + case 2: + mpfr_set_inf (mpc_realref (z1), +1); + break; + case 3: + mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); + break; + case 4: + mpfr_set_inf (mpc_imagref (z1), -1); + break; + case 5: + mpfr_set_ui (mpc_realref (z2), 0, GMP_RNDN); + break; + case 6: + mpfr_set_inf (mpc_realref (z2), -1); + break; + case 7: + mpfr_set_ui (mpc_imagref (z2), 0, GMP_RNDN); + break; + case 8: + mpfr_set_inf (mpc_imagref (z2), +1); + break; + } + break; + case CCCC: + mpc_set_prec (z2, prec); + test_default_random (z2, exp_min, exp_max, 128, zero_probability); + mpc_set_prec (z3, prec); + mpc_set_prec (z4, prec); + mpc_set_prec (z5, prec); + mpc_set_prec (zzzz, 4*prec); + switch (special) + { + case 1: + mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); + break; + case 2: + mpfr_set_inf (mpc_realref (z1), +1); + break; + case 3: + mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); + break; + case 4: + mpfr_set_inf (mpc_imagref (z1), -1); + break; + case 5: + mpfr_set_ui (mpc_realref (z2), 0, GMP_RNDN); + break; + case 6: + mpfr_set_inf (mpc_realref (z2), -1); + break; + case 7: + mpfr_set_ui (mpc_imagref (z2), 0, GMP_RNDN); + break; + case 8: + mpfr_set_inf (mpc_imagref (z2), +1); + break; + } + break; + case FC: + mpc_set_prec (z2, prec); + mpfr_set_prec (x1, prec); + mpfr_set_prec (x2, prec); + mpfr_set_prec (xxxx, 4*prec); + switch (special) + { + case 1: + mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); + break; + case 2: + mpfr_set_inf (mpc_realref (z1), +1); + break; + case 3: + mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); + break; + case 4: + mpfr_set_inf (mpc_imagref (z1), -1); + break; + } + break; + case CCU: case CUC: + mpc_set_prec (z2, 128); + do { + test_default_random (z2, 0, 64, 128, zero_probability); + } while (!mpfr_fits_ulong_p (mpc_realref (z2), GMP_RNDN)); + ul1 = mpfr_get_ui (mpc_realref(z2), GMP_RNDN); + mpc_set_prec (z2, prec); + mpc_set_prec (z3, prec); + mpc_set_prec (zzzz, 4*prec); + switch (special) + { + case 1: + mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); + break; + case 2: + mpfr_set_inf (mpc_realref (z1), +1); + break; + case 3: + mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); + break; + case 4: + mpfr_set_inf (mpc_imagref (z1), -1); + break; + case 5: + ul1 = 0; + break; + } + break; + case CUUC: + mpc_set_prec (z2, 128); + do { + test_default_random (z2, 0, 64, 128, zero_probability); + } while (!mpfr_fits_ulong_p (mpc_realref (z2), GMP_RNDN) + ||!mpfr_fits_ulong_p (mpc_imagref (z2), GMP_RNDN)); + ul1 = mpfr_get_ui (mpc_realref(z2), GMP_RNDN); + ul2 = mpfr_get_ui (mpc_imagref(z2), GMP_RNDN); + mpc_set_prec (z2, prec); + mpc_set_prec (z3, prec); + mpc_set_prec (zzzz, 4*prec); + switch (special) + { + case 1: + mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); + break; + case 2: + mpfr_set_inf (mpc_realref (z1), +1); + break; + case 3: + mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); + break; + case 4: + mpfr_set_inf (mpc_imagref (z1), -1); + break; + case 5: + ul1 = 0; + break; + case 6: + ul2 = 0; + break; + } + break; + case CCS: + mpc_set_prec (z2, 128); + do { + test_default_random (z2, 0, 64, 128, zero_probability); + } while (!mpfr_fits_slong_p (mpc_realref (z2), GMP_RNDN)); + lo = mpfr_get_si (mpc_realref(z2), GMP_RNDN); + mpc_set_prec (z2, prec); + mpc_set_prec (z3, prec); + mpc_set_prec (zzzz, 4*prec); + switch (special) + { + case 1: + mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); + break; + case 2: + mpfr_set_inf (mpc_realref (z1), +1); + break; + case 3: + mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); + break; + case 4: + mpfr_set_inf (mpc_imagref (z1), -1); + break; + case 5: + lo = 0; + break; + } + break; + case CCI: + mpc_set_prec (z2, 128); + do { + test_default_random (z2, 0, 64, 128, zero_probability); + } while (!mpfr_fits_slong_p (mpc_realref (z2), GMP_RNDN)); + i = (int)mpfr_get_si (mpc_realref(z2), GMP_RNDN); + mpc_set_prec (z2, prec); + mpc_set_prec (z3, prec); + mpc_set_prec (zzzz, 4*prec); + switch (special) + { + case 1: + mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); + break; + case 2: + mpfr_set_inf (mpc_realref (z1), +1); + break; + case 3: + mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); + break; + case 4: + mpfr_set_inf (mpc_imagref (z1), -1); + break; + case 5: + i = 0; + break; + } + break; + case CCF: case CFC: + mpfr_set_prec (x1, prec); + mpfr_set (x1, mpc_realref (z1), GMP_RNDN); + test_default_random (z1, exp_min, exp_max, 128, zero_probability); + mpc_set_prec (z2, prec); + mpc_set_prec (z3, prec); + mpc_set_prec (zzzz, 4*prec); + switch (special) + { + case 1: + mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); + break; + case 2: + mpfr_set_inf (mpc_realref (z1), +1); + break; + case 3: + mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); + break; + case 4: + mpfr_set_inf (mpc_imagref (z1), -1); + break; + case 5: + mpfr_set_ui (x1, 0, GMP_RNDN); + break; + case 6: + mpfr_set_inf (x1, +1); + break; + } + break; + case CC_C: + mpc_set_prec (z2, prec); + mpc_set_prec (z3, prec); + mpc_set_prec (z4, prec); + mpc_set_prec (z5, prec); + mpc_set_prec (zzzz, 4*prec); + mpc_set_prec (zzzz2, 4*prec); + switch (special) + { + case 1: + mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); + break; + case 2: + mpfr_set_inf (mpc_realref (z1), +1); + break; + case 3: + mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); + break; + case 4: + mpfr_set_inf (mpc_imagref (z1), -1); + break; + } + break; + case CC: + default: + mpc_set_prec (z2, prec); + mpc_set_prec (z3, prec); + mpc_set_prec (zzzz, 4*prec); + switch (special) + { + case 1: + mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); + break; + case 2: + mpfr_set_inf (mpc_realref (z1), +1); + break; + case 3: + mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); + break; + case 4: + mpfr_set_inf (mpc_imagref (z1), -1); + break; + } + } + + for (rnd_re = first_rnd_mode (); is_valid_rnd_mode (rnd_re); rnd_re = next_rnd_mode (rnd_re)) + switch (function.type) + { + case C_CC: + for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) + tgeneric_c_cc (&function, z1, z2, z3, zzzz, z4, + MPC_RND (rnd_re, rnd_im)); + reuse_c_cc (&function, z1, z2, z3, z4); + break; + case CCCC: + for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) + tgeneric_cccc (&function, z1, z2, z3, z4, zzzz, z5, + MPC_RND (rnd_re, rnd_im)); + reuse_cccc (&function, z1, z2, z3, z4, z5); + break; + case FC: + tgeneric_fc (&function, z1, x1, xxxx, x2, rnd_re); + reuse_fc (&function, z1, z2, x1); + break; + case CC: + for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) + tgeneric_cc (&function, z1, z2, zzzz, z3, + MPC_RND (rnd_re, rnd_im)); + reuse_cc (&function, z1, z2, z3); + break; + case CC_C: + for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) + for (rnd2_re = first_rnd_mode (); is_valid_rnd_mode (rnd2_re); rnd2_re = next_rnd_mode (rnd2_re)) + for (rnd2_im = first_rnd_mode (); is_valid_rnd_mode (rnd2_im); rnd2_im = next_rnd_mode (rnd2_im)) + tgeneric_cc_c (&function, z1, z2, z3, zzzz, zzzz2, z4, z5, + MPC_RND (rnd_re, rnd_im), MPC_RND (rnd2_re, rnd2_im)); + reuse_cc_c (&function, z1, z2, z3, z4, z5); + break; + case CFC: + for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) + tgeneric_cfc (&function, x1, z1, z2, zzzz, z3, + MPC_RND (rnd_re, rnd_im)); + reuse_cfc (&function, z1, x1, z2, z3); + break; + case CCF: + for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) + tgeneric_ccf (&function, z1, x1, z2, zzzz, z3, + MPC_RND (rnd_re, rnd_im)); + reuse_ccf (&function, z1, x1, z2, z3); + break; + case CCU: + for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) + tgeneric_ccu (&function, z1, ul1, z2, zzzz, z3, + MPC_RND (rnd_re, rnd_im)); + reuse_ccu (&function, z1, ul1, z2, z3); + break; + case CUC: + for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) + tgeneric_cuc (&function, ul1, z1, z2, zzzz, z3, + MPC_RND (rnd_re, rnd_im)); + reuse_cuc (&function, ul1, z1, z2, z3); + break; + case CCS: + for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) + tgeneric_ccs (&function, z1, lo, z2, zzzz, z3, + MPC_RND (rnd_re, rnd_im)); + reuse_ccs (&function, z1, lo, z2, z3); + break; + case CCI: + for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) + tgeneric_cci (&function, z1, i, z2, zzzz, z3, + MPC_RND (rnd_re, rnd_im)); + reuse_cci (&function, z1, i, z2, z3); + break; + case CUUC: + for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) + tgeneric_cuuc (&function, ul1, ul2, z1, z2, zzzz, z3, + MPC_RND (rnd_re, rnd_im)); + reuse_cuuc (&function, ul1, ul2, z1, z2, z3); + break; + default: + printf ("tgeneric not yet implemented for this kind of" + "function\n"); + exit (1); + } + } + + mpc_clear (z1); + switch (function.type) + { + case C_CC: + mpc_clear (z2); + mpc_clear (z3); + mpc_clear (z4); + mpc_clear (zzzz); + break; + case CCCC: + mpc_clear (z2); + mpc_clear (z3); + mpc_clear (z4); + mpc_clear (z5); + mpc_clear (zzzz); + break; + case FC: + mpc_clear (z2); + mpfr_clear (x1); + mpfr_clear (x2); + mpfr_clear (xxxx); + break; + case CCF: case CFC: + mpfr_clear (x1); + mpc_clear (z2); + mpc_clear (z3); + mpc_clear (zzzz); + break; + case CC_C: + mpc_clear (z2); + mpc_clear (z3); + mpc_clear (z4); + mpc_clear (z5); + mpc_clear (zzzz); + mpc_clear (zzzz2); + break; + case CUUC: + case CCI: case CCS: + case CCU: case CUC: + case CC: + default: + mpc_clear (z2); + mpc_clear (z3); + mpc_clear (zzzz); + } +} |