diff options
Diffstat (limited to 'mpc/tests/read_data.c')
-rw-r--r-- | mpc/tests/read_data.c | 1059 |
1 files changed, 1059 insertions, 0 deletions
diff --git a/mpc/tests/read_data.c b/mpc/tests/read_data.c new file mode 100644 index 0000000000..7f3d91f622 --- /dev/null +++ b/mpc/tests/read_data.c @@ -0,0 +1,1059 @@ +/* read_data,c -- Read data file and check function. + +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 <stdlib.h> +#include <string.h> +#include "mpc-tests.h" + +char *pathname; +unsigned long line_number; + /* file name with complete path and currently read line; + kept globally to simplify parameter passing */ +unsigned long test_line_number; + /* start line of data test (which may extend over several lines) */ +int nextchar; + /* character appearing next in the file, may be EOF */ + +#define MPC_INEX_CMP(r, i, c) \ + (((r) == TERNARY_NOT_CHECKED || (r) == MPC_INEX_RE(c)) \ + && ((i) == TERNARY_NOT_CHECKED || (i) == MPC_INEX_IM (c))) + +#define MPFR_INEX_STR(inex) \ + (inex) == TERNARY_NOT_CHECKED ? "?" \ + : (inex) == +1 ? "+1" \ + : (inex) == -1 ? "-1" : "0" + +static const char *mpfr_rnd_mode [] = + { "GMP_RNDN", "GMP_RNDZ", "GMP_RNDU", "GMP_RNDD" }; + +const char *rnd_mode[] = + { "MPC_RNDNN", "MPC_RNDZN", "MPC_RNDUN", "MPC_RNDDN", + "undefined", "undefined", "undefined", "undefined", "undefined", + "undefined", "undefined", "undefined", "undefined", "undefined", + "undefined", "undefined", + "MPC_RNDNZ", "MPC_RNDZZ", "MPC_RNDUZ", "MPC_RNDDZ", + "undefined", "undefined", "undefined", "undefined", "undefined", + "undefined", "undefined", "undefined", "undefined", "undefined", + "undefined", "undefined", + "MPC_RNDNU", "MPC_RNDZU", "MPC_RNDUU", "MPC_RNDDU", + "undefined", "undefined", "undefined", "undefined", "undefined", + "undefined", "undefined", "undefined", "undefined", "undefined", + "undefined", "undefined", + "MPC_RNDND", "MPC_RNDZD", "MPC_RNDUD", "MPC_RNDDD", + "undefined", "undefined", "undefined", "undefined", "undefined", + "undefined", "undefined", "undefined", "undefined", "undefined", + "undefined", "undefined", + }; + +/* file functions */ +FILE * +open_data_file (const char *file_name) +{ + FILE *fp; + char *src_dir; + char default_srcdir[] = "."; + + src_dir = getenv ("srcdir"); + if (src_dir == NULL) + src_dir = default_srcdir; + + pathname = (char *) malloc ((strlen (src_dir)) + strlen (file_name) + 2); + if (pathname == NULL) + { + printf ("Cannot allocate memory\n"); + exit (1); + } + sprintf (pathname, "%s/%s", src_dir, file_name); + fp = fopen (pathname, "r"); + if (fp == NULL) + { + fprintf (stderr, "Unable to open %s\n", pathname); + exit (1); + } + + return fp; +} + +void +close_data_file (FILE *fp) +{ + free (pathname); + fclose (fp); +} + +/* read primitives */ +static void +skip_line (FILE *fp) + /* skips characters until reaching '\n' or EOF; */ + /* '\n' is skipped as well */ +{ + while (nextchar != EOF && nextchar != '\n') + nextchar = getc (fp); + if (nextchar != EOF) + { + line_number ++; + nextchar = getc (fp); + } +} + +static void +skip_whitespace (FILE *fp) + /* skips over whitespace if any until reaching EOF */ + /* or non-whitespace */ +{ + while (isspace (nextchar)) + { + if (nextchar == '\n') + line_number ++; + nextchar = getc (fp); + } +} + +void +skip_whitespace_comments (FILE *fp) + /* skips over all whitespace and comments, if any */ +{ + skip_whitespace (fp); + while (nextchar == '#') { + skip_line (fp); + if (nextchar != EOF) + skip_whitespace (fp); + } +} + + +size_t +read_string (FILE *fp, char **buffer_ptr, size_t buffer_length, const char *name) +{ + size_t pos; + char *buffer; + + pos = 0; + buffer = *buffer_ptr; + + if (nextchar == '"') + nextchar = getc (fp); + else + goto error; + + while (nextchar != EOF && nextchar != '"') + { + if (nextchar == '\n') + line_number ++; + if (pos + 1 > buffer_length) + { + buffer = (char *) realloc (buffer, 2 * buffer_length); + if (buffer == NULL) + { + printf ("Cannot allocate memory\n"); + exit (1); + } + buffer_length *= 2; + } + buffer[pos++] = (char) nextchar; + nextchar = getc (fp); + } + + if (nextchar != '"') + goto error; + + if (pos + 1 > buffer_length) + { + buffer = (char *) realloc (buffer, buffer_length + 1); + if (buffer == NULL) + { + printf ("Cannot allocate memory\n"); + exit (1); + } + buffer_length *= 2; + } + buffer[pos] = '\0'; + + nextchar = getc (fp); + skip_whitespace_comments (fp); + + *buffer_ptr = buffer; + + return buffer_length; + + error: + printf ("Error: Unable to read %s in file '%s' line '%lu'\n", + name, pathname, line_number); + exit (1); +} + +/* All following read routines skip over whitespace and comments; */ +/* so after calling them, nextchar is either EOF or the beginning */ +/* of a non-comment token. */ +void +read_ternary (FILE *fp, int* ternary) +{ + switch (nextchar) + { + case '!': + *ternary = TERNARY_ERROR; + break; + case '?': + *ternary = TERNARY_NOT_CHECKED; + break; + case '+': + *ternary = +1; + break; + case '0': + *ternary = 0; + break; + case '-': + *ternary = -1; + break; + default: + printf ("Error: Unexpected ternary value '%c' in file '%s' line %lu\n", + nextchar, pathname, line_number); + exit (1); + } + + nextchar = getc (fp); + skip_whitespace_comments (fp); +} + +void +read_mpfr_rounding_mode (FILE *fp, mpfr_rnd_t* rnd) +{ + switch (nextchar) + { + case 'n': case 'N': + *rnd = GMP_RNDN; + break; + case 'z': case 'Z': + *rnd = GMP_RNDZ; + break; + case 'u': case 'U': + *rnd = GMP_RNDU; + break; + case 'd': case 'D': + *rnd = GMP_RNDD; + break; + default: + printf ("Error: Unexpected rounding mode '%c' in file '%s' line %lu\n", + nextchar, pathname, line_number); + exit (1); + } + + nextchar = getc (fp); + if (nextchar != EOF && !isspace (nextchar)) { + printf ("Error: Rounding mode not followed by white space in file " + "'%s' line %lu\n", + pathname, line_number); + exit (1); + } + skip_whitespace_comments (fp); +} + +void +read_mpc_rounding_mode (FILE *fp, mpc_rnd_t* rnd) +{ + mpfr_rnd_t re, im; + read_mpfr_rounding_mode (fp, &re); + read_mpfr_rounding_mode (fp, &im); + *rnd = MPC_RND (re, im); +} + +void +read_int (FILE *fp, int *nread, const char *name) +{ + int n = 0; + + if (nextchar == EOF) + { + printf ("Error: Unexpected EOF when reading int " + "in file '%s' line %lu\n", + pathname, line_number); + exit (1); + } + ungetc (nextchar, fp); + n = fscanf (fp, "%i", nread); + if (ferror (fp) || n == 0 || n == EOF) + { + printf ("Error: Cannot read %s in file '%s' line %lu\n", + name, pathname, line_number); + exit (1); + } + nextchar = getc (fp); + skip_whitespace_comments (fp); +} + +static void +read_uint (FILE *fp, unsigned long int *ui) +{ + int n = 0; + + if (nextchar == EOF) + { + printf ("Error: Unexpected EOF when reading uint " + "in file '%s' line %lu\n", + pathname, line_number); + exit (1); + } + ungetc (nextchar, fp); + n = fscanf (fp, "%lu", ui); + if (ferror (fp) || n == 0 || n == EOF) + { + printf ("Error: Cannot read uint in file '%s' line %lu\n", + pathname, line_number); + exit (1); + } + nextchar = getc (fp); + skip_whitespace_comments (fp); +} + +static void +read_sint (FILE *fp, long int *si) +{ + int n = 0; + + if (nextchar == EOF) + { + printf ("Error: Unexpected EOF when reading sint " + "in file '%s' line %lu\n", + pathname, line_number); + exit (1); + } + ungetc (nextchar, fp); + n = fscanf (fp, "%li", si); + if (ferror (fp) || n == 0 || n == EOF) + { + printf ("Error: Cannot read sint in file '%s' line %lu\n", + pathname, line_number); + exit (1); + } + nextchar = getc (fp); + skip_whitespace_comments (fp); +} + +mpfr_prec_t +read_mpfr_prec (FILE *fp) +{ + unsigned long prec; + int n; + + if (nextchar == EOF) { + printf ("Error: Unexpected EOF when reading mpfr precision " + "in file '%s' line %lu\n", + pathname, line_number); + exit (1); + } + ungetc (nextchar, fp); + n = fscanf (fp, "%lu", &prec); + if (ferror (fp)) /* then also n == EOF */ + perror ("Error when reading mpfr precision"); + if (n == 0 || n == EOF || prec < MPFR_PREC_MIN || prec > MPFR_PREC_MAX) { + printf ("Error: Impossible mpfr precision in file '%s' line %lu\n", + pathname, line_number); + exit (1); + } + nextchar = getc (fp); + skip_whitespace_comments (fp); + return (mpfr_prec_t) prec; +} + +static void +read_mpfr_mantissa (FILE *fp, mpfr_ptr x) +{ + if (nextchar == EOF) { + printf ("Error: Unexpected EOF when reading mpfr mantissa " + "in file '%s' line %lu\n", + pathname, line_number); + exit (1); + } + ungetc (nextchar, fp); + if (mpfr_inp_str (x, fp, 0, GMP_RNDN) == 0) { + printf ("Error: Impossible to read mpfr mantissa " + "in file '%s' line %lu\n", + pathname, line_number); + exit (1); + } + nextchar = getc (fp); + skip_whitespace_comments (fp); +} + +void +read_mpfr (FILE *fp, mpfr_ptr x, int *known_sign) +{ + int sign; + mpfr_set_prec (x, read_mpfr_prec (fp)); + sign = nextchar; + read_mpfr_mantissa (fp, x); + + /* the sign always matters for regular values ('+' is implicit), + but when no sign appears before 0 or Inf in the data file, it means + that only absolute value must be checked. */ + if (known_sign != NULL) + *known_sign = + (!mpfr_zero_p (x) && !mpfr_inf_p (x)) + || sign == '+' || sign == '-'; +} + +void +read_mpc (FILE *fp, mpc_ptr z, known_signs_t *ks) +{ + read_mpfr (fp, mpc_realref (z), ks == NULL ? NULL : &ks->re); + read_mpfr (fp, mpc_imagref (z), ks == NULL ? NULL : &ks->im); +} + +static void +check_compatible (int inex, mpfr_t expected, mpfr_rnd_t rnd, const char *s) +{ + if ((rnd == GMP_RNDU && inex == -1) || + (rnd == GMP_RNDD && inex == +1) || + (rnd == GMP_RNDZ && !mpfr_signbit (expected) && inex == +1) || + (rnd == GMP_RNDZ && mpfr_signbit (expected) && inex == -1)) + { + if (s != NULL) + printf ("Incompatible ternary value '%c' (%s part) in file '%s' line %lu\n", + (inex == 1) ? '+' : '-', s, pathname, test_line_number); + else + printf ("Incompatible ternary value '%c' in file '%s' line %lu\n", + (inex == 1) ? '+' : '-', pathname, test_line_number); + } +} + +/* read lines of data */ +static void +read_cc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, + known_signs_t *signs, mpc_ptr op, mpc_rnd_t *rnd) +{ + test_line_number = line_number; + read_ternary (fp, inex_re); + read_ternary (fp, inex_im); + read_mpc (fp, expected, signs); + read_mpc (fp, op, NULL); + read_mpc_rounding_mode (fp, rnd); + check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); + check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); +} + +static void +read_fc (FILE *fp, int *inex, mpfr_ptr expected, int *sign, mpc_ptr op, + mpfr_rnd_t *rnd) +{ + test_line_number = line_number; + read_ternary (fp, inex); + read_mpfr (fp, expected, sign); + read_mpc (fp, op, NULL); + read_mpfr_rounding_mode (fp, rnd); + check_compatible (*inex, expected, *rnd, NULL); +} + +static void +read_ccc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, + known_signs_t *signs, mpc_ptr op1, mpc_ptr op2, mpc_rnd_t *rnd) +{ + test_line_number = line_number; + read_ternary (fp, inex_re); + read_ternary (fp, inex_im); + read_mpc (fp, expected, signs); + read_mpc (fp, op1, NULL); + read_mpc (fp, op2, NULL); + read_mpc_rounding_mode (fp, rnd); + check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); + check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); +} + +/* read lines of data for function with three mpc_t inputs and one mpc_t + output like mpc_fma */ +static void +read_cccc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, + known_signs_t *signs, mpc_ptr op1, mpc_ptr op2, mpc_ptr op3, + mpc_rnd_t *rnd) +{ + test_line_number = line_number; + read_ternary (fp, inex_re); + read_ternary (fp, inex_im); + read_mpc (fp, expected, signs); + read_mpc (fp, op1, NULL); + read_mpc (fp, op2, NULL); + read_mpc (fp, op3, NULL); + read_mpc_rounding_mode (fp, rnd); + check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); + check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); +} + +static void +read_cfc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, + known_signs_t *signs, mpfr_ptr op1, mpc_ptr op2, mpc_rnd_t *rnd) +{ + test_line_number = line_number; + read_ternary (fp, inex_re); + read_ternary (fp, inex_im); + read_mpc (fp, expected, signs); + read_mpfr (fp, op1, NULL); + read_mpc (fp, op2, NULL); + read_mpc_rounding_mode (fp, rnd); + check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); + check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); +} + +static void +read_ccf (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, + known_signs_t *signs, mpc_ptr op1, mpfr_ptr op2, mpc_rnd_t *rnd) +{ + test_line_number = line_number; + read_ternary (fp, inex_re); + read_ternary (fp, inex_im); + read_mpc (fp, expected, signs); + read_mpc (fp, op1, NULL); + read_mpfr (fp, op2, NULL); + read_mpc_rounding_mode (fp, rnd); + check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); + check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); +} + +static void +read_ccu (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, + known_signs_t *signs, mpc_ptr op1, unsigned long int *op2, mpc_rnd_t *rnd) +{ + test_line_number = line_number; + read_ternary (fp, inex_re); + read_ternary (fp, inex_im); + read_mpc (fp, expected, signs); + read_mpc (fp, op1, NULL); + read_uint (fp, op2); + read_mpc_rounding_mode (fp, rnd); + check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); + check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); +} + +static void +read_ccs (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, + known_signs_t *signs, mpc_ptr op1, long int *op2, mpc_rnd_t *rnd) +{ + test_line_number = line_number; + read_ternary (fp, inex_re); + read_ternary (fp, inex_im); + read_mpc (fp, expected, signs); + read_mpc (fp, op1, NULL); + read_sint (fp, op2); + read_mpc_rounding_mode (fp, rnd); + check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); + check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); +} + +/* set MPFR flags to random values */ +static void +set_mpfr_flags (int counter) +{ + if (counter & 1) + mpfr_set_underflow (); + else + mpfr_clear_underflow (); + if (counter & 2) + mpfr_set_overflow (); + else + mpfr_clear_overflow (); + /* the divide-by-0 flag was added in MPFR 3.1.0 */ +#ifdef mpfr_set_divby0 + if (counter & 4) + mpfr_set_divby0 (); + else + mpfr_clear_divby0 (); +#endif + if (counter & 8) + mpfr_set_nanflag (); + else + mpfr_clear_nanflag (); + if (counter & 16) + mpfr_set_inexflag (); + else + mpfr_clear_inexflag (); + if (counter & 32) + mpfr_set_erangeflag (); + else + mpfr_clear_erangeflag (); +} + +/* Check MPFR flags: we allow that some flags are set internally by MPC, + for example if MPC does internal computations (using MPFR) which yield + an overflow, even if the final MPC result fits in the exponent range. + However we don't allow MPC to *clear* the MPFR flags */ +static void +check_mpfr_flags (int counter) +{ + int old, neu; + + old = (counter & 1) != 0; + neu = mpfr_underflow_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, underflow flag has been modified from %d to %d\n", + old, neu); + exit (1); + } + old = (counter & 2) != 0; + neu = mpfr_overflow_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, overflow flag has been modified from %d to %d\n", + old, neu); + exit (1); + } +#ifdef mpfr_divby0_p + old = (counter & 4) != 0; + neu = mpfr_divby0_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, divby0 flag has been modified from %d to %d\n", + old, neu); + exit (1); + } +#endif + old = (counter & 8) != 0; + neu = mpfr_nanflag_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, nanflag flag has been modified from %d to %d\n", + old, neu); + exit (1); + } + old = (counter & 16) != 0; + neu = mpfr_inexflag_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, inexflag flag has been modified from %d to %d\n", + old, neu); + exit (1); + } + old = (counter & 32) != 0; + neu = mpfr_erangeflag_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, erangeflag flag has been modified from %d to %d\n", + old, neu); + exit (1); + } +} + +/* data_check (function, data_file_name) checks function results against + precomputed data in a file.*/ +void +data_check (mpc_function function, const char *file_name) +{ + FILE *fp; + + int inex_re; + mpfr_t x1, x2; + mpfr_rnd_t mpfr_rnd = GMP_RNDN; + int sign_real; + + int inex_im; + mpc_t z1, z2, z3, z4, z5; + mpc_rnd_t rnd = MPC_RNDNN; + + unsigned long int ui; + long int si; + + known_signs_t signs; + int inex = 0; + + static int rand_counter = 0; + + fp = open_data_file (file_name); + + /* 1. init needed variables */ + mpc_init2 (z1, 2); + switch (function.type) + { + case FC: + mpfr_init (x1); + mpfr_init (x2); + break; + case CC: case CCU: case CCS: + mpc_init2 (z2, 2); + mpc_init2 (z3, 2); + break; + case C_CC: + mpc_init2 (z2, 2); + mpc_init2 (z3, 2); + mpc_init2 (z4, 2); + break; + case CCCC: + mpc_init2 (z2, 2); + mpc_init2 (z3, 2); + mpc_init2 (z4, 2); + mpc_init2 (z5, 2); + break; + case CFC: case CCF: + mpfr_init (x1); + mpc_init2 (z2, 2); + mpc_init2 (z3, 2); + break; + default: + ; + } + + /* 2. read data file */ + line_number = 1; + nextchar = getc (fp); + skip_whitespace_comments (fp); + while (nextchar != EOF) { + set_mpfr_flags (rand_counter); + + /* for each kind of function prototype: */ + /* 3.1 read a line of data: expected result, parameters, rounding mode */ + /* 3.2 compute function at the same precision as the expected result */ + /* 3.3 compare this result with the expected one */ + switch (function.type) + { + case FC: /* example mpc_norm */ + read_fc (fp, &inex_re, x1, &sign_real, z1, &mpfr_rnd); + mpfr_set_prec (x2, mpfr_get_prec (x1)); + inex = function.pointer.FC (x2, z1, mpfr_rnd); + if ((inex_re != TERNARY_NOT_CHECKED && inex_re != inex) + || !same_mpfr_value (x1, x2, sign_real)) + { + mpfr_t got, expected; + mpc_t op; + op[0] = z1[0]; + got[0] = x2[0]; + expected[0] = x1[0]; + printf ("%s(op) failed (%s:%lu)\nwith rounding mode %s\n", + function.name, file_name, test_line_number, + mpfr_rnd_mode[mpfr_rnd]); + if (inex_re != TERNARY_NOT_CHECKED && inex_re != inex) + printf("ternary value: got %s, expected %s\n", + MPFR_INEX_STR (inex), MPFR_INEX_STR (inex_re)); + MPC_OUT (op); + printf (" "); + MPFR_OUT (got); + MPFR_OUT (expected); + + exit (1); + } + break; + + case CC: /* example mpc_log */ + read_cc (fp, &inex_re, &inex_im, z1, &signs, z2, &rnd); + mpfr_set_prec (mpc_realref (z3), MPC_PREC_RE (z1)); + mpfr_set_prec (mpc_imagref (z3), MPC_PREC_IM (z1)); + inex = function.pointer.CC (z3, z2, rnd); + if (!MPC_INEX_CMP (inex_re, inex_im, inex) + || !same_mpc_value (z3, z1, signs)) + { + mpc_t op, got, expected; /* display sensible variable names */ + op[0] = z2[0]; + expected[0]= z1[0]; + got[0] = z3[0]; + printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", + function.name, test_line_number, rnd_mode[rnd]); + if (!MPC_INEX_CMP (inex_re, inex_im, inex)) + printf("ternary value: got %s, expected (%s, %s)\n", + MPC_INEX_STR (inex), + MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); + MPC_OUT (op); + printf (" "); + MPC_OUT (got); + MPC_OUT (expected); + + exit (1); + } + break; + + case C_CC: /* example mpc_mul */ + read_ccc (fp, &inex_re, &inex_im, z1, &signs, z2, z3, &rnd); + mpfr_set_prec (mpc_realref(z4), MPC_PREC_RE (z1)); + mpfr_set_prec (mpc_imagref(z4), MPC_PREC_IM (z1)); + inex = function.pointer.C_CC (z4, z2, z3, rnd); + if (!MPC_INEX_CMP (inex_re, inex_im, inex) + || !same_mpc_value (z4, z1, signs)) + { + /* display sensible variable names */ + mpc_t op1, op2, got, expected; + op1[0] = z2[0]; + op2[0] = z3[0]; + expected[0]= z1[0]; + got[0] = z4[0]; + printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", + function.name, test_line_number, rnd_mode[rnd]); + if (!MPC_INEX_CMP (inex_re, inex_im, inex)) + printf("ternary value: got %s, expected (%s, %s)\n", + MPC_INEX_STR (inex), + MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); + MPC_OUT (op1); + MPC_OUT (op2); + printf (" "); + MPC_OUT (got); + MPC_OUT (expected); + + exit (1); + } + if (function.properties & FUNC_PROP_SYMETRIC) + { + inex = function.pointer.C_CC (z4, z3, z2, rnd); + if (!MPC_INEX_CMP (inex_re, inex_im, inex) + || !same_mpc_value (z4, z1, signs)) + { + /* display sensible variable names */ + mpc_t op1, op2, got, expected; + op1[0] = z3[0]; + op2[0] = z2[0]; + expected[0]= z1[0]; + got[0] = z4[0]; + printf ("%s(op) failed (line %lu/symetric test)\n" + "with rounding mode %s\n", + function.name, test_line_number, rnd_mode[rnd]); + if (!MPC_INEX_CMP (inex_re, inex_im, inex)) + printf("ternary value: got %s, expected (%s, %s)\n", + MPC_INEX_STR (inex), + MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); + MPC_OUT (op1); + MPC_OUT (op2); + printf (" "); + MPC_OUT (got); + MPC_OUT (expected); + + exit (1); + } + } + break; + + case CCCC: /* example mpc_fma */ + read_cccc (fp, &inex_re, &inex_im, z1, &signs, z2, z3, z4, &rnd); + /* z1 is the expected value, z2, z3, z4 are the inputs, and z5 is + the computed value */ + mpfr_set_prec (mpc_realref(z5), MPC_PREC_RE (z1)); + mpfr_set_prec (mpc_imagref(z5), MPC_PREC_IM (z1)); + inex = function.pointer.CCCC (z5, z2, z3, z4, rnd); + if (!MPC_INEX_CMP (inex_re, inex_im, inex) + || !same_mpc_value (z5, z1, signs)) + { + /* display sensible variable names */ + mpc_t op1, op2, op3, got, expected; + op1[0] = z2[0]; + op2[0] = z3[0]; + op3[0] = z4[0]; + expected[0]= z1[0]; + got[0] = z5[0]; + printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", + function.name, test_line_number, rnd_mode[rnd]); + if (!MPC_INEX_CMP (inex_re, inex_im, inex)) + printf("ternary value: got %s, expected (%s, %s)\n", + MPC_INEX_STR (inex), + MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); + MPC_OUT (op1); + MPC_OUT (op2); + MPC_OUT (op3); + printf (" "); + MPC_OUT (got); + MPC_OUT (expected); + + exit (1); + } + if (function.properties & FUNC_PROP_SYMETRIC) + { + inex = function.pointer.CCCC (z5, z3, z2, z4, rnd); + if (!MPC_INEX_CMP (inex_re, inex_im, inex) + || !same_mpc_value (z5, z1, signs)) + { + /* display sensible variable names */ + mpc_t op1, op2, op3, got, expected; + op1[0] = z3[0]; + op2[0] = z2[0]; + op3[0] = z4[0]; + expected[0]= z1[0]; + got[0] = z5[0]; + printf ("%s(op) failed (line %lu/symetric test)\n" + "with rounding mode %s\n", + function.name, test_line_number, rnd_mode[rnd]); + if (!MPC_INEX_CMP (inex_re, inex_im, inex)) + printf("ternary value: got %s, expected (%s, %s)\n", + MPC_INEX_STR (inex), + MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); + MPC_OUT (op1); + MPC_OUT (op2); + MPC_OUT (op3); + printf (" "); + MPC_OUT (got); + MPC_OUT (expected); + + exit (1); + } + } + break; + + case CFC: /* example mpc_fr_div */ + read_cfc (fp, &inex_re, &inex_im, z1, &signs, x1, z2, &rnd); + mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1)); + mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1)); + inex = function.pointer.CFC (z3, x1, z2, rnd); + if (!MPC_INEX_CMP (inex_re, inex_im, inex) + || !same_mpc_value (z3, z1, signs)) + { + /* display sensible variable names */ + mpc_t op2, got, expected; + mpfr_t op1; + op1[0] = x1[0]; + op2[0] = z2[0]; + expected[0]= z1[0]; + got[0] = z3[0]; + printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", + function.name, test_line_number, rnd_mode[rnd]); + if (!MPC_INEX_CMP (inex_re, inex_im, inex)) + printf("ternary value: got %s, expected (%s, %s)\n", + MPC_INEX_STR (inex), + MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); + MPFR_OUT (op1); + MPC_OUT (op2); + printf (" "); + MPC_OUT (got); + MPC_OUT (expected); + + exit (1); + } + break; + + case CCF: /* example mpc_mul_fr */ + read_ccf (fp, &inex_re, &inex_im, z1, &signs, z2, x1, &rnd); + mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1)); + mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1)); + inex = function.pointer.CCF (z3, z2, x1, rnd); + if (!MPC_INEX_CMP (inex_re, inex_im, inex) + || !same_mpc_value (z3, z1, signs)) + { + /* display sensible variable names */ + mpc_t op1, got, expected; + mpfr_t op2; + op1[0] = z2[0]; + op2[0] = x1[0]; + expected[0]= z1[0]; + got[0] = z3[0]; + printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", + function.name, test_line_number, rnd_mode[rnd]); + if (!MPC_INEX_CMP (inex_re, inex_im, inex)) + printf("ternary value: got %s, expected (%s, %s)\n", + MPC_INEX_STR (inex), + MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); + MPC_OUT (op1); + MPFR_OUT (op2); + printf (" "); + MPC_OUT (got); + MPC_OUT (expected); + + exit (1); + } + break; + + case CCU: /* example mpc_pow_ui */ + read_ccu (fp, &inex_re, &inex_im, z1, &signs, z2, &ui, &rnd); + mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1)); + mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1)); + inex = function.pointer.CCU (z3, z2, ui, rnd); + if (!MPC_INEX_CMP (inex_re, inex_im, inex) + || !same_mpc_value (z3, z1, signs)) + { + /* display sensible variable names */ + mpc_t op1, got, expected; + op1[0] = z2[0]; + expected[0]= z1[0]; + got[0] = z3[0]; + printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", + function.name, test_line_number, rnd_mode[rnd]); + if (!MPC_INEX_CMP (inex_re, inex_im, inex)) + printf("ternary value: got %s, expected (%s, %s)\n", + MPC_INEX_STR (inex), + MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); + MPC_OUT (op1); + printf ("op2 %lu\n ", ui); + MPC_OUT (got); + MPC_OUT (expected); + + exit (1); + } + break; + + case CCS: /* example mpc_pow_si */ + read_ccs (fp, &inex_re, &inex_im, z1, &signs, z2, &si, &rnd); + mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1)); + mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1)); + inex = function.pointer.CCS (z3, z2, si, rnd); + if (!MPC_INEX_CMP (inex_re, inex_im, inex) + || !same_mpc_value (z3, z1, signs)) + { + /* display sensible variable names */ + mpc_t op1, got, expected; + op1[0] = z2[0]; + expected[0]= z1[0]; + got[0] = z3[0]; + printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", + function.name, test_line_number, rnd_mode[rnd]); + if (!MPC_INEX_CMP (inex_re, inex_im, inex)) + printf("ternary value: got %s, expected (%s, %s)\n", + MPC_INEX_STR (inex), + MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); + MPC_OUT (op1); + printf ("op2 %li\n ", si); + MPC_OUT (got); + MPC_OUT (expected); + + exit (1); + } + break; + + default: + printf ("Unhandled function prototype %i in 'data_check'\n", function.type); + exit (1); + } + + /* check MPFR flags were not modified */ + check_mpfr_flags (rand_counter); + rand_counter ++; + } + + /* 3. Clear used variables */ + mpc_clear (z1); + switch (function.type) + { + case FC: + mpfr_clear (x1); + mpfr_clear (x2); + break; + case CC: case CCU: case CCS: + mpc_clear (z2); + mpc_clear (z3); + break; + case C_CC: + mpc_clear (z2); + mpc_clear (z3); + mpc_clear (z4); + break; + case CCCC: + mpc_clear (z2); + mpc_clear (z3); + mpc_clear (z4); + mpc_clear (z5); + break; + case CFC: case CCF: + mpfr_clear (x1); + mpc_clear (z2); + mpc_clear (z3); + break; + default: + ; + } + + close_data_file (fp); +} |