summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthevenyp <thevenyp@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2014-01-22 10:09:07 +0000
committerthevenyp <thevenyp@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2014-01-22 10:09:07 +0000
commitf8e19d05072cb3e7bc32fc093868fdf73fa9a232 (patch)
tree28044abea340c7a5fefa24e36d2318131081c2bd
parent9936d02411e3446fb64e5fd8fb8e5671af25dbf1 (diff)
downloadmpc-f8e19d05072cb3e7bc32fc093868fdf73fa9a232.tar.gz
[tests] Support of sin_cos with the new test framework.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@1422 211d60ee-9f03-0410-a15a-8952a2c7a4e4
-rw-r--r--tests/check_data.c5
-rw-r--r--tests/clear_parameters.c3
-rw-r--r--tests/copy_parameter.c3
-rw-r--r--tests/double_rounding.c65
-rw-r--r--tests/init_parameters.c3
-rw-r--r--tests/mpc-tests.h19
-rw-r--r--tests/print_parameter.c7
-rw-r--r--tests/read_description.c9
-rw-r--r--tests/read_line.c9
-rw-r--r--tests/rounding.c126
-rw-r--r--tests/sin_cos.dsc4
-rw-r--r--tests/tgeneric.tpl3
-rw-r--r--tests/tsin_cos.c262
13 files changed, 198 insertions, 320 deletions
diff --git a/tests/check_data.c b/tests/check_data.c
index 6d6bc69..f834955 100644
--- a/tests/check_data.c
+++ b/tests/check_data.c
@@ -1,6 +1,6 @@
/* check_data.c -- Check computed data against reference result.
-Copyright (C) 2012, 2013 INRIA
+Copyright (C) 2012, 2013, 2014 INRIA
This file is part of GNU MPC.
@@ -62,6 +62,9 @@ check_param (mpc_operand_t* got, mpc_operand_t* expected, mpc_param_t t)
return tpl_check_mpc_data (got->mpc,
expected->mpc_data);
+ case MPCC_INEX:
+ return got->mpcc_inex == expected->mpcc_inex;
+
default:
fprintf (stderr, "check_data: unsupported type.\n");
exit (1);
diff --git a/tests/clear_parameters.c b/tests/clear_parameters.c
index d5c74f8..cded00c 100644
--- a/tests/clear_parameters.c
+++ b/tests/clear_parameters.c
@@ -1,6 +1,6 @@
/* clear_parameters -- Deallocate memory for function parameters.
-Copyright (C) 2012, 2013 INRIA
+Copyright (C) 2012, 2013, 2014 INRIA
This file is part of GNU MPC.
@@ -48,6 +48,7 @@ clear_param (mpc_operand_t* p, mpc_param_t t)
break;
case MPC_INEX:
+ case MPCC_INEX:
break;
case MPC:
mpc_clear (p->mpc);
diff --git a/tests/copy_parameter.c b/tests/copy_parameter.c
index 4c1ff37..8147019 100644
--- a/tests/copy_parameter.c
+++ b/tests/copy_parameter.c
@@ -1,7 +1,7 @@
/* copy_parameter.c -- Copy of an input parameter into a parameter reused for
output.
-Copyright (C) 2012, 2013 INRIA
+Copyright (C) 2012, 2013, 2014 INRIA
This file is part of GNU MPC.
@@ -113,6 +113,7 @@ copy_parameter (mpc_fun_param_t *params, int index_dest, int index_src)
case NATIVE_STRING:
case MPFR_INEX: case MPFR_RND:
case MPC_INEX: case MPC_RND:
+ case MPCC_INEX:
/* no supported copy */
break;
}
diff --git a/tests/double_rounding.c b/tests/double_rounding.c
index 6181d1a..601ba1a 100644
--- a/tests/double_rounding.c
+++ b/tests/double_rounding.c
@@ -1,6 +1,6 @@
/* double_rounding.c -- Functions for checking double rounding.
-Copyright (C) 2013 INRIA
+Copyright (C) 2013, 2014 INRIA
This file is part of GNU MPC.
@@ -35,7 +35,7 @@ double_rounding_mpfr (mpfr_ptr lowprec,
if (hiprec_rnd == MPFR_RNDN)
/* when rounding to nearest, use the trick for determining the
- correct ternary value which is described in MPFR
+ correct ternary value which is described in the MPFR
documentation */
{
hiprec_err++; /* error is bounded by one half-ulp */
@@ -74,42 +74,75 @@ double_rounding (mpc_fun_param_t *params)
{
int out;
const int offset = params->nbout + params->nbin;
- const int rnd_index = params->nbout + params->nbin - 1;
+ int rnd_index = offset - params->nbrnd;
for (out = 0; out < params->nbout; out++) {
if (params->T[out] == MPC)
{
- MPC_ASSERT (params->T[0] == MPC_INEX);
- MPC_ASSERT (params->T[offset] == MPC_INEX);
+ int inex;
+
+ MPC_ASSERT ((params->T[0] == MPC_INEX)
+ || (params->T[0] == MPCC_INEX));
+ MPC_ASSERT ((params->T[offset] == MPC_INEX)
+ || (params->T[offset] == MPCC_INEX));
MPC_ASSERT (params->T[out + offset] == MPC);
MPC_ASSERT (params->T[rnd_index] == MPC_RND);
+ /*
+ For the time being, there may be either one or two rounding modes;
+ in the latter case, we assume that there are three outputs:
+ the inexact value and two complex numbers.
+ */
+ inex = (params->nbrnd == 1 ? params->P[0].mpc_inex
+ : (out == 1 ? MPC_INEX1 (params->P[0].mpcc_inex)
+ : MPC_INEX2 (params->P[0].mpcc_inex)));
+
if (double_rounding_mpc (params->P[out + offset].mpc_data.mpc,
params->P[out].mpc,
- params->P[0].mpc_inex,
+ inex,
params->P[rnd_index].mpc_rnd))
- /* the hight-precision value and the exact value round to the same
+ /* the high-precision value and the exact value round to the same
low-precision value */
{
- int inex;
+ int inex_hp, inex_re, inex_im;
inex = mpc_set (params->P[out + offset].mpc_data.mpc,
params->P[out].mpc,
params->P[rnd_index].mpc_rnd);
params->P[out + offset].mpc_data.known_sign_real = -1;
params->P[out + offset].mpc_data.known_sign_imag = -1;
- /* no double rounding means that the ternary value may comes from
+ /* no double rounding means that the ternary value may come from
the high-precision calculation or from the rounding */
+ if (params->nbrnd == 1)
+ inex_hp = params->P[0].mpc_inex;
+ else /* nbrnd == 2 */
+ if (out == 1)
+ inex_hp = MPC_INEX1 (params->P[0].mpcc_inex);
+ else /* out == 2 */
+ inex_hp = MPC_INEX2 (params->P[0].mpcc_inex);
+
if (MPC_INEX_RE (inex) == 0)
- params->P[offset].mpc_inex_data.real =
- MPC_INEX_RE (params->P[0].mpc_inex);
+ inex_re = MPC_INEX_RE (inex_hp);
else
- params->P[offset].mpc_inex_data.real = MPC_INEX_RE (inex);
+ inex_re = MPC_INEX_RE (inex);
if (MPC_INEX_IM (inex) == 0)
- params->P[offset].mpc_inex_data.imag =
- MPC_INEX_IM (params->P[0].mpc_inex);
+ inex_im = MPC_INEX_IM (inex_hp);
else
- params->P[offset].mpc_inex_data.imag = MPC_INEX_IM (inex);
+ inex_im = MPC_INEX_IM (inex);
+
+ if (params->nbrnd == 1) {
+ params->P[offset].mpc_inex_data.real = inex_re;
+ params->P[offset].mpc_inex_data.imag = inex_im;
+ }
+ else /* nbrnd == 2 */
+ if (out == 1)
+ params->P[offset].mpcc_inex = MPC_INEX (inex_re, inex_im);
+ else /* out == 2 */
+ params->P[offset].mpcc_inex
+ = MPC_INEX12 (params->P[offset].mpcc_inex,
+ MPC_INEX (inex_re, inex_im));
+
+ rnd_index++;
}
else
/* double rounding occurs */
@@ -141,6 +174,8 @@ double_rounding (mpc_fun_param_t *params)
params->P[offset].mpfr_inex = params->P[0].mpfr_inex;
else
params->P[offset].mpfr_inex = inex;
+
+ rnd_index++;
}
else
/* double rounding occurs */
diff --git a/tests/init_parameters.c b/tests/init_parameters.c
index ea94a34..a439c0b 100644
--- a/tests/init_parameters.c
+++ b/tests/init_parameters.c
@@ -1,6 +1,6 @@
/* init_parameters -- Allocate memory for function parameters.
-Copyright (C) 2012 INRIA
+Copyright (C) 2012, 2014 INRIA
This file is part of GNU MPC.
@@ -49,6 +49,7 @@ init_param (mpc_operand_t* p, mpc_param_t t)
break;
case MPC_INEX:
+ case MPCC_INEX:
break;
case MPC:
mpc_init2 (p->mpc, 512);
diff --git a/tests/mpc-tests.h b/tests/mpc-tests.h
index 19027a5..8a33da8 100644
--- a/tests/mpc-tests.h
+++ b/tests/mpc-tests.h
@@ -1,6 +1,6 @@
/* mpc-tests.h -- Tests helper functions.
-Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 INRIA
+Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014 INRIA
This file is part of GNU MPC.
@@ -179,7 +179,8 @@ typedef enum {
MPFR_RND, /* mpfr_rnd_t */
MPC_INEX, /* mpc_inex */
MPC, /* mpc_t */
- MPC_RND /* mpc_rnd_t */
+ MPC_RND, /* mpc_rnd_t */
+ MPCC_INEX /* mpcc_inex */
} mpc_param_t;
/* additional information for checking mpfr_t result */
@@ -255,15 +256,25 @@ typedef union {
mpc_rnd_t mpc_rnd;
int mpc_inex;
mpc_inex_data_t mpc_inex_data;
+ int mpcc_inex;
} mpc_operand_t;
#define PARAMETER_ARRAY_SIZE 10
-/* function name plus parameters */
+/* function name plus parameters in the following order:
+ output parameters, input parameters (ending with rounding modes).
+ The input parameters include one rounding mode per mpfr/mpc
+ output starting from rnd_index.
+ For the time being, there may be either one or two rounding modes;
+ in the latter case, we assume that there are three outputs:
+ the inexact value and two complex numbers.
+ */
typedef struct {
char *name; /* name of the function */
int nbout; /* number of output parameters */
- int nbin; /* number of input parameters */
+ int nbin; /* number of input parameters, including rounding
+ modes */
+ int nbrnd; /* number of rounding mode parameters */
mpc_operand_t P[PARAMETER_ARRAY_SIZE]; /* value of parameters */
mpc_param_t T[PARAMETER_ARRAY_SIZE]; /* type of parameters */
} mpc_fun_param_t;
diff --git a/tests/print_parameter.c b/tests/print_parameter.c
index e7820c8..3ae502b 100644
--- a/tests/print_parameter.c
+++ b/tests/print_parameter.c
@@ -118,6 +118,13 @@ print_parameter (mpc_fun_param_t* params, int index)
mpc_rnd_mode[params->P[index].mpc_rnd]);
break;
+ case MPCC_INEX:
+ printf (" double ternary value = %s, %s\n",
+ MPC_INEX_STR (MPC_INEX1 (params->P[index].mpcc_inex)),
+ MPC_INEX_STR (MPC_INEX2 (params->P[index].mpcc_inex))
+ );
+ break;
+
default:
fprintf (stderr, "print_parameter: unsupported type.\n");
exit (1);
diff --git a/tests/read_description.c b/tests/read_description.c
index 8a02265..f706b69 100644
--- a/tests/read_description.c
+++ b/tests/read_description.c
@@ -56,7 +56,8 @@ static const param_typeval_t sparam_typeval[]= {
{ "mpc_inex" , MPC_INEX },
{ "mpc_ptr" , MPC },
{ "mpc_srcptr" , MPC },
- { "mpc_rnd_t" , MPC_RND }
+ { "mpc_rnd_t" , MPC_RND },
+ { "mpcc_inex" , MPCC_INEX }
};
/* read primitives */
@@ -166,6 +167,7 @@ read_description (mpc_fun_param_t* param, const char *filename)
size_t len = 0;
int nbout = 0;
int nbin = 0;
+ int rnd_mode = 0;
int j;
open_datafile (&datafile_context, filename);
@@ -251,12 +253,15 @@ read_description (mpc_fun_param_t* param, const char *filename)
if (strlen (buffer) == 0 && feof (datafile_context.fd))
break;
param->T[nbout+nbin] = description_findtype (buffer);
+ if (param->T[nbout+nbin] == MPC_RND || param->T[nbout+nbin] == MPFR_RND)
+ rnd_mode++;
nbin++;
}
free (buffer);
param->nbout = nbout;
- param->nbin = nbin;
+ param->nbin = nbin;
+ param->nbrnd = rnd_mode;
/* duplicate output parameters at the end for the expected values */
for (j = 0; j < param->nbout; j++)
diff --git a/tests/read_line.c b/tests/read_line.c
index 3fb29c5..cde5db8 100644
--- a/tests/read_line.c
+++ b/tests/read_line.c
@@ -1,6 +1,6 @@
/* read_line.c -- Read line of test data in file.
-Copyright (C) 2012, 2013 INRIA
+Copyright (C) 2012, 2013, 2014 INRIA
This file is part of GNU MPC.
@@ -98,6 +98,12 @@ read_param (mpc_datafile_context_t* datafile_context,
case MPC_RND:
tpl_read_mpc_rnd (datafile_context, &p->mpc_rnd);
return;
+
+ case MPCC_INEX:
+ /* TODO */
+ fprintf (stderr, "read_param: type not implemented.\n");
+ exit (1);
+ break;
}
fprintf (stderr, "read_param: unsupported type.\n");
@@ -134,6 +140,7 @@ set_precision (mpc_fun_param_t* params, int index)
case GMP_F:
case MPFR_INEX: case MPFR_RND:
case MPC_INEX: case MPC_RND:
+ case MPCC_INEX:
/* unsupported types */
break;
}
diff --git a/tests/rounding.c b/tests/rounding.c
index 603e627..86c4321 100644
--- a/tests/rounding.c
+++ b/tests/rounding.c
@@ -1,6 +1,6 @@
/* rounding.c -- file for functions iterating over rounding modes.
-Copyright (C) 2013 INRIA
+Copyright (C) 2013, 2014 INRIA
This file is part of GNU MPC.
@@ -56,21 +56,45 @@ is_valid_mpfr_rnd_mode (mpfr_rnd_t curr)
return 0;
}
+static mpc_rnd_t
+next_mpc_rnd_mode (mpc_rnd_t rnd)
+{
+ mpfr_rnd_t rnd_re = MPC_RND_RE (rnd);
+ mpfr_rnd_t rnd_im = MPC_RND_IM (rnd);
+
+ rnd_im = next_mpfr_rnd_mode (rnd_im);
+ if (!is_valid_mpfr_rnd_mode (rnd_im))
+ {
+ rnd_re = next_mpfr_rnd_mode (rnd_re);
+ rnd_im = FIRST_MPFR_RND_MODE;
+ }
+
+ return MPC_RND(rnd_re, rnd_im);
+}
+
+static int
+is_valid_mpc_rnd_mode (mpc_rnd_t rnd)
+/* returns 1 if curr is a valid rounding mode, and 0 otherwise */
+{
+ mpfr_rnd_t rnd_re = MPC_RND_RE (rnd);
+ mpfr_rnd_t rnd_im = MPC_RND_IM (rnd);
+
+ return is_valid_mpfr_rnd_mode (rnd_re) && is_valid_mpfr_rnd_mode (rnd_im);
+}
/* functions using abstract parameters */
-void
-first_rnd_mode (mpc_fun_param_t *params)
+static void
+first_mode (mpc_fun_param_t *params, int index)
{
- int rnd_mode_index = params->nbout + params->nbin - 1;
- switch (params->T[rnd_mode_index])
+ switch (params->T[index])
{
case MPC_RND:
- params->P[rnd_mode_index].mpc_rnd =
+ params->P[index].mpc_rnd =
MPC_RND(FIRST_MPFR_RND_MODE, FIRST_MPFR_RND_MODE);
break;
case MPFR_RND:
- params->P[rnd_mode_index].mpfr_rnd = FIRST_MPFR_RND_MODE;
+ params->P[index].mpfr_rnd = FIRST_MPFR_RND_MODE;
break;
default:
printf ("The rounding mode is expected to be"
@@ -79,27 +103,18 @@ first_rnd_mode (mpc_fun_param_t *params)
}
}
-void
-next_rnd_mode (mpc_fun_param_t *params)
+static void
+next_mode (mpc_fun_param_t *params, int index)
{
- mpfr_rnd_t rnd_re, rnd_im;
- int rnd_mode_index = params->nbout + params->nbin - 1;
- switch (params->T[rnd_mode_index])
+ switch (params->T[index])
{
case MPC_RND:
- rnd_re = MPC_RND_RE (params->P[rnd_mode_index].mpc_rnd);
- rnd_im = MPC_RND_IM (params->P[rnd_mode_index].mpc_rnd);
- rnd_im = next_mpfr_rnd_mode (rnd_im);
- if (!is_valid_mpfr_rnd_mode (rnd_im))
- {
- rnd_re = next_mpfr_rnd_mode (rnd_re);
- rnd_im = FIRST_MPFR_RND_MODE;
- }
- params->P[rnd_mode_index].mpc_rnd = MPC_RND(rnd_re, rnd_im);
+ params->P[index].mpc_rnd =
+ next_mpc_rnd_mode (params->P[index].mpc_rnd);
break;
case MPFR_RND:
- params->P[rnd_mode_index].mpfr_rnd =
- next_mpfr_rnd_mode (params->P[rnd_mode_index].mpfr_rnd);
+ params->P[index].mpfr_rnd =
+ next_mpfr_rnd_mode (params->P[index].mpfr_rnd);
break;
default:
printf ("The rounding mode is expected to be"
@@ -108,24 +123,67 @@ next_rnd_mode (mpc_fun_param_t *params)
}
}
-int
-is_valid_rnd_mode (mpc_fun_param_t *params)
-/* returns 1 if curr is a valid rounding mode, and 0 otherwise */
+static int
+is_valid_mode (mpc_fun_param_t *params, int index)
+/* returns 1 if params->P[index] is a valid rounding mode, and 0 otherwise */
{
- mpfr_rnd_t rnd_re, rnd_im;
- int rnd_mode_index = params->nbout + params->nbin - 1;
- switch (params->T[rnd_mode_index])
+ switch (params->T[index])
{
case MPC_RND:
- rnd_re = MPC_RND_RE (params->P[rnd_mode_index].mpc_rnd);
- rnd_im = MPC_RND_IM (params->P[rnd_mode_index].mpc_rnd);
- return is_valid_mpfr_rnd_mode (rnd_re)
- && is_valid_mpfr_rnd_mode (rnd_im);
+ return is_valid_mpc_rnd_mode (params->P[index].mpc_rnd);
case MPFR_RND:
- return is_valid_mpfr_rnd_mode (params->P[rnd_mode_index].mpfr_rnd);
+ return is_valid_mpfr_rnd_mode (params->P[index].mpfr_rnd);
default:
printf ("The rounding mode is expected to be"
" the last input parameter.\n");
exit (-1);
}
}
+
+void
+first_rnd_mode (mpc_fun_param_t *params)
+{
+ int rnd_mode_index;
+
+ for (rnd_mode_index = params->nbout + params->nbin - params->nbrnd;
+ rnd_mode_index < params->nbout + params->nbin;
+ rnd_mode_index++)
+ {
+ first_mode (params, rnd_mode_index);
+ }
+}
+
+
+void
+next_rnd_mode (mpc_fun_param_t *params)
+/* cycle through all valid rounding modes and finish with an invalid one */
+{
+ int last = params->nbout + params->nbin - 1;
+ int index = params->nbout + params->nbin - params->nbrnd;
+ int carry = 1;
+
+ while (carry && index <= last) {
+ next_mode (params, index);
+ if (!is_valid_mode (params, index) && index < last)
+ first_mode (params, index);
+ else
+ carry = 0;
+ index++;
+ }
+}
+
+int
+is_valid_rnd_mode (mpc_fun_param_t *params)
+/* returns 1 if all rounding parameters are set to a valid rounding mode,
+ and 0 otherwise */
+{
+ int index;
+
+ for (index = params->nbout + params->nbin - params->nbrnd;
+ index < params->nbout + params->nbin;
+ index++)
+ if (! is_valid_mode (params, index))
+ return 0;
+
+ return 1;
+}
diff --git a/tests/sin_cos.dsc b/tests/sin_cos.dsc
index ddefe79..0bcecd4 100644
--- a/tests/sin_cos.dsc
+++ b/tests/sin_cos.dsc
@@ -1,6 +1,6 @@
# Description file for mpc_sin_cos
#
-# Copyright (C) 2013 INRIA
+# Copyright (C) 2013, 2014 INRIA
#
# This file is part of GNU MPC.
#
@@ -20,7 +20,7 @@
NAME:
mpc_sin_cos
RETURN:
- mpc_inex
+ mpcc_inex
OUTPUT:
mpc_ptr
mpc_ptr
diff --git a/tests/tgeneric.tpl b/tests/tgeneric.tpl
index 22b2548..57a55a7 100644
--- a/tests/tgeneric.tpl
+++ b/tests/tgeneric.tpl
@@ -1,6 +1,6 @@
/* tgeneric.tpl -- template file for generic tests.
-Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 INRIA
+Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014 INRIA
This file is part of GNU MPC.
@@ -320,6 +320,7 @@ random_params (mpc_fun_param_t *params,
case NATIVE_STRING:
case MPFR_INEX:
case MPC_INEX:
+ case MPCC_INEX:
/* unsupported types */
fprintf (stderr, "random_params: unsupported type.\n");
exit (1);
diff --git a/tests/tsin_cos.c b/tests/tsin_cos.c
index ae1b1c8..0d67d83 100644
--- a/tests/tsin_cos.c
+++ b/tests/tsin_cos.c
@@ -1,6 +1,6 @@
/* tsin_cos -- test file for mpc_sin_cos.
-Copyright (C) 2011, 2013 INRIA
+Copyright (C) 2011, 2013, 2014 INRIA
This file is part of GNU MPC.
@@ -20,269 +20,17 @@ along with this program. If not, see http://www.gnu.org/licenses/ .
#include "mpc-tests.h"
-static void random_params (mpc_fun_param_t *params,
- mpfr_exp_t exp_min, mpfr_exp_t exp_max,
- int special);
-static void check_against_quadruple_precision (mpc_fun_param_t *params,
- mpc_fun_param_t *params_sin,
- mpc_fun_param_t *params_cos,
- mpfr_prec_t prec,
- mpfr_exp_t exp_min,
- mpfr_exp_t exp_max,
- int special);
+#define MPC_FUNCTION_CALL \
+ P[0].mpcc_inex = mpc_sin_cos (P[1].mpc, P[2].mpc, P[3].mpc, P[4].mpc_rnd, P[5].mpc_rnd)
-/* tgeneric(desc, 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.
- - for pure real, pure imaginary and infinite random parameters.
-
- It also checks parameter reuse.
-*/
-static void
-tgeneric_custom (mpfr_prec_t prec_min, mpfr_prec_t prec_max, mpfr_prec_t step,
- mpfr_exp_t exp_max)
-{
- int special = 0;
- const int last_special = 8;
- mpfr_prec_t prec;
- mpfr_exp_t exp_min;
- mpc_fun_param_t params;
- mpc_fun_param_t params_sin;
- mpc_fun_param_t params_cos;
-
- read_description (&params, "sin_cos.dsc");
- init_parameters (&params);
- read_description (&params_sin, "sin.dsc");
- init_parameters (&params_sin);
- read_description (&params_cos, "cos.dsc");
- init_parameters (&params_cos);
-
- /* ask for enough memory */
- set_output_precision (&params, 4 * prec_max);
- set_input_precision (&params, prec_max);
- set_reference_precision (&params, prec_max);
- set_output_precision (&params_sin, 4 * prec_max);
- set_input_precision (&params_sin, prec_max);
- set_reference_precision (&params_sin, prec_max);
- set_output_precision (&params_cos, 4 * prec_max);
- set_input_precision (&params_cos, prec_max);
- set_reference_precision (&params_cos, prec_max);
-
- /* sanity checks */
- 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;
-
- /* check consistency with quadruple precision for random parameters */
- for (prec = prec_min; prec <= prec_max; prec += step)
- check_against_quadruple_precision (&params, &params_sin, &params_cos,
- prec, exp_min, exp_max, -1);
-
- /* check consistency with quadruple precision for special values:
- pure real, pure imaginary, or infinite arguments */
- for (special = 0; special < last_special ; special++)
- check_against_quadruple_precision (&params, &params_sin, &params_cos,
- prec_max, exp_min, exp_max,
- special);
-
- clear_parameters (&params);
- clear_parameters (&params_sin);
- clear_parameters (&params_cos);
-}
-
-static void
-filter_params (mpc_fun_param_t *params_sin_cos,
- mpc_fun_param_t *params,
- int index)
-{
- /* inex */
- params->P[0].mpc_inex = (index == 0) ?
- MPC_INEX1 (params_sin_cos->P[0].mpc_inex)
- : MPC_INEX2 (params_sin_cos->P[0].mpc_inex);
-
- /* output */
- mpc_set (params->P[1].mpc, params_sin_cos->P[1 + index].mpc, MPC_RNDNN);
-
- /* input */
- mpc_set (params->P[2].mpc, params_sin_cos->P[3].mpc, MPC_RNDNN);
-
- /* rnd mode is already set */
-}
-
-static void
-gather_params (mpc_fun_param_t *params_sin_cos,
- mpc_fun_param_t *params_sin,
- mpc_fun_param_t *params_cos)
-{
- /* do not check inex value */
- params_sin_cos->P[6].mpc_inex_data.real = TERNARY_NOT_CHECKED;
- params_sin_cos->P[6].mpc_inex_data.imag = TERNARY_NOT_CHECKED;
-
- mpc_set (params_sin_cos->P[7].mpc_data.mpc,
- params_sin->P[5].mpc_data.mpc,
- MPC_RNDNN);
- params_sin_cos->P[7].mpc_data.known_sign_real = -1;
- params_sin_cos->P[7].mpc_data.known_sign_imag = -1;
-
- mpc_set (params_sin_cos->P[8].mpc_data.mpc,
- params_cos->P[5].mpc_data.mpc,
- MPC_RNDNN);
- params_sin_cos->P[8].mpc_data.known_sign_real = -1;
- params_sin_cos->P[8].mpc_data.known_sign_imag = -1;
-}
-
-static void
-gather_rounding_modes (mpc_fun_param_t *params_sin_cos,
- mpc_fun_param_t *params_sin,
- mpc_fun_param_t *params_cos)
-{
- params_sin_cos->P[4].mpc_rnd = params_sin->P[3].mpc_rnd;
- params_sin_cos->P[5].mpc_rnd = params_cos->P[3].mpc_rnd;
-}
-
-static void
-check_against_quadruple_precision (mpc_fun_param_t *params,
- mpc_fun_param_t *params_sin,
- mpc_fun_param_t *params_cos,
- mpfr_prec_t prec,
- mpfr_exp_t exp_min, mpfr_exp_t exp_max,
- int special)
-{
- mpc_operand_t *P = params->P; /* developer-friendly alias, used in macros */
-
- set_input_precision (params, prec);
- set_reference_precision (params, prec);
- set_output_precision (params, 4 * prec);
-
- set_input_precision (params_sin, prec);
- set_reference_precision (params_sin, prec);
- set_output_precision (params_sin, 4 * prec);
-
- set_input_precision (params_cos, prec);
- set_reference_precision (params_cos, prec);
- set_output_precision (params_cos, 4 * prec);
-
-
- for (first_rnd_mode (params_sin);
- is_valid_rnd_mode (params_sin);
- next_rnd_mode (params_sin))
- {
- for (first_rnd_mode (params_cos);
- is_valid_rnd_mode (params_cos);
- next_rnd_mode (params_cos))
- {
- gather_rounding_modes (params, params_sin, params_cos);
- do
- {
- random_params (params, exp_min, exp_max, special);
- P[0].mpc_inex = mpc_sin_cos (P[1].mpc, P[2].mpc, P[3].mpc,
- P[4].mpc_rnd, P[5].mpc_rnd);
- filter_params (params, params_sin, 0);
- filter_params (params, params_cos, 1);
- } while (double_rounding (params_sin)
- || double_rounding (params_cos));
- gather_params (params, params_sin, params_cos);
-
- set_output_precision (params, prec);
- P[0].mpc_inex = mpc_sin_cos (P[1].mpc, P[2].mpc, P[3].mpc,
- P[4].mpc_rnd, P[5].mpc_rnd);
- check_data (NULL, params, 0);
-
- set_output_precision (params, 4 * prec);
- }
- }
-}
-
-
-/* special cases */
-
-enum {
- SPECIAL_MINF,
- SPECIAL_MZERO,
- SPECIAL_PZERO,
- SPECIAL_PINF,
- SPECIAL_COUNT
-};
-
-static void
-special_mpfr (mpfr_ptr x, int special)
-{
- switch (special)
- {
- case SPECIAL_MINF:
- mpfr_set_inf (x, -1);
- break;
- case SPECIAL_MZERO:
- mpfr_set_zero (x, -1);
- break;
- case SPECIAL_PZERO:
- mpfr_set_zero (x, +1);
- break;
- case SPECIAL_PINF:
- mpfr_set_inf (x, +1);
- break;
- }
-}
-
-static void
-special_random_mpc (mpc_ptr z, mpfr_exp_t exp_min, mpfr_exp_t exp_max,
- int special)
-{
- mpfr_ptr special_part;
- mpfr_ptr random_part;
- int mpfr_special;
-
- if (special < SPECIAL_COUNT)
- {
- mpfr_special = special;
- special_part = mpc_realref (z);
- random_part = mpc_imagref (z);
- }
- else
- {
- mpfr_special = special - SPECIAL_COUNT;
- special_part = mpc_imagref (z);
- random_part = mpc_realref (z);
- }
-
- special_mpfr (special_part, mpfr_special);
- test_random_mpfr (random_part, exp_min, exp_max, 128);
-}
-
-static void
-random_params (mpc_fun_param_t *params,
- mpfr_exp_t exp_min, mpfr_exp_t exp_max,
- int special)
-{
- int i;
- int base_index = 0;
- const int start = params->nbout;
- const int end = start + params->nbin - 2;
-
- for (i = start; i < end; i++)
- {
- if (base_index <= special
- && special - base_index < 2 * SPECIAL_COUNT)
- special_random_mpc (params->P[i].mpc, exp_min, exp_max,
- special - base_index);
- else
- test_random_mpc (params->P[i].mpc, exp_min, exp_max, 128);
- base_index += 2 * SPECIAL_COUNT;
- }
-}
+#include "tgeneric.tpl"
int
main (void)
{
test_start ();
- tgeneric_custom (2, 512, 13, 7);
+ tgeneric_template ("sin_cos.dsc", 2, 512, 13, 7);
test_end ();