#include "mpc-tests.h"
#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)))
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};
function->pointer.CC (rop4, op, rnd);
function->pointer.CC (rop, op, 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 (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)
{
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)) {
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)) {
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);
}
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};
function->pointer.C_CC (rop4, op1, op2, rnd);
function->pointer.C_CC (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);
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};
function->pointer.CCCC (rop4, op1, op2, op3, rnd);
function->pointer.CCCC (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);
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);
}
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);
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);
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);
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);
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];
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);
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];
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);
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);
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);
}
}
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
}
}
static mpfr_rnd_t
first_rnd_mode (void)
{
return GMP_RNDN;
}
static mpfr_rnd_t
next_rnd_mode (mpfr_rnd_t curr)
{
switch (curr) {
case GMP_RNDN:
return GMP_RNDZ;
case GMP_RNDZ:
return GMP_RNDU;
case GMP_RNDU:
return GMP_RNDD;
default:
#if MPFR_VERSION_MAJOR < 3
return GMP_RNDNA;
#else
return MPFR_RNDA;
#endif
}
}
static int
is_valid_rnd_mode (mpfr_rnd_t curr)
{
if ( curr == GMP_RNDN || curr == GMP_RNDZ
|| curr == GMP_RNDU || curr == GMP_RNDD)
return 1;
else
return 0;
}
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)) {
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);
}
}