Home | History | Annotate | Line # | Download | only in tests
read_data.c revision 1.1
      1  1.1  mrg /* read_data,c -- Read data file and check function.
      2  1.1  mrg 
      3  1.1  mrg Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA
      4  1.1  mrg 
      5  1.1  mrg This file is part of GNU MPC.
      6  1.1  mrg 
      7  1.1  mrg GNU MPC is free software; you can redistribute it and/or modify it under
      8  1.1  mrg the terms of the GNU Lesser General Public License as published by the
      9  1.1  mrg Free Software Foundation; either version 3 of the License, or (at your
     10  1.1  mrg option) any later version.
     11  1.1  mrg 
     12  1.1  mrg GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
     13  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
     14  1.1  mrg FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
     15  1.1  mrg more details.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU Lesser General Public License
     18  1.1  mrg along with this program. If not, see http://www.gnu.org/licenses/ .
     19  1.1  mrg */
     20  1.1  mrg 
     21  1.1  mrg #include <stdlib.h>
     22  1.1  mrg #include <string.h>
     23  1.1  mrg #include "mpc-tests.h"
     24  1.1  mrg 
     25  1.1  mrg char *pathname;
     26  1.1  mrg unsigned long line_number;
     27  1.1  mrg    /* file name with complete path and currently read line;
     28  1.1  mrg       kept globally to simplify parameter passing */
     29  1.1  mrg unsigned long test_line_number;
     30  1.1  mrg    /* start line of data test (which may extend over several lines) */
     31  1.1  mrg int nextchar;
     32  1.1  mrg    /* character appearing next in the file, may be EOF */
     33  1.1  mrg 
     34  1.1  mrg #define MPC_INEX_CMP(r, i, c)                                 \
     35  1.1  mrg   (((r) == TERNARY_NOT_CHECKED || (r) == MPC_INEX_RE(c))      \
     36  1.1  mrg    && ((i) == TERNARY_NOT_CHECKED || (i) == MPC_INEX_IM (c)))
     37  1.1  mrg 
     38  1.1  mrg #define MPFR_INEX_STR(inex)                     \
     39  1.1  mrg   (inex) == TERNARY_NOT_CHECKED ? "?"           \
     40  1.1  mrg     : (inex) == +1 ? "+1"                       \
     41  1.1  mrg     : (inex) == -1 ? "-1" : "0"
     42  1.1  mrg 
     43  1.1  mrg static const char *mpfr_rnd_mode [] =
     44  1.1  mrg   { "GMP_RNDN", "GMP_RNDZ", "GMP_RNDU", "GMP_RNDD" };
     45  1.1  mrg 
     46  1.1  mrg const char *rnd_mode[] =
     47  1.1  mrg   { "MPC_RNDNN", "MPC_RNDZN", "MPC_RNDUN", "MPC_RNDDN",
     48  1.1  mrg     "undefined", "undefined", "undefined", "undefined", "undefined",
     49  1.1  mrg     "undefined", "undefined", "undefined", "undefined", "undefined",
     50  1.1  mrg     "undefined", "undefined",
     51  1.1  mrg     "MPC_RNDNZ", "MPC_RNDZZ", "MPC_RNDUZ", "MPC_RNDDZ",
     52  1.1  mrg     "undefined", "undefined", "undefined", "undefined", "undefined",
     53  1.1  mrg     "undefined", "undefined", "undefined", "undefined", "undefined",
     54  1.1  mrg     "undefined", "undefined",
     55  1.1  mrg     "MPC_RNDNU", "MPC_RNDZU", "MPC_RNDUU", "MPC_RNDDU",
     56  1.1  mrg     "undefined", "undefined", "undefined", "undefined", "undefined",
     57  1.1  mrg     "undefined", "undefined", "undefined", "undefined", "undefined",
     58  1.1  mrg     "undefined", "undefined",
     59  1.1  mrg     "MPC_RNDND", "MPC_RNDZD", "MPC_RNDUD", "MPC_RNDDD",
     60  1.1  mrg     "undefined", "undefined", "undefined", "undefined", "undefined",
     61  1.1  mrg     "undefined", "undefined", "undefined", "undefined", "undefined",
     62  1.1  mrg     "undefined", "undefined",
     63  1.1  mrg   };
     64  1.1  mrg 
     65  1.1  mrg /* file functions */
     66  1.1  mrg FILE *
     67  1.1  mrg open_data_file (const char *file_name)
     68  1.1  mrg {
     69  1.1  mrg   FILE *fp;
     70  1.1  mrg   char *src_dir;
     71  1.1  mrg   char default_srcdir[] = ".";
     72  1.1  mrg 
     73  1.1  mrg   src_dir = getenv ("srcdir");
     74  1.1  mrg   if (src_dir == NULL)
     75  1.1  mrg     src_dir = default_srcdir;
     76  1.1  mrg 
     77  1.1  mrg   pathname = (char *) malloc ((strlen (src_dir)) + strlen (file_name) + 2);
     78  1.1  mrg   if (pathname == NULL)
     79  1.1  mrg     {
     80  1.1  mrg       printf ("Cannot allocate memory\n");
     81  1.1  mrg       exit (1);
     82  1.1  mrg     }
     83  1.1  mrg   sprintf (pathname, "%s/%s", src_dir, file_name);
     84  1.1  mrg   fp = fopen (pathname, "r");
     85  1.1  mrg   if (fp == NULL)
     86  1.1  mrg     {
     87  1.1  mrg       fprintf (stderr, "Unable to open %s\n", pathname);
     88  1.1  mrg       exit (1);
     89  1.1  mrg     }
     90  1.1  mrg 
     91  1.1  mrg   return fp;
     92  1.1  mrg }
     93  1.1  mrg 
     94  1.1  mrg void
     95  1.1  mrg close_data_file (FILE *fp)
     96  1.1  mrg {
     97  1.1  mrg   free (pathname);
     98  1.1  mrg   fclose (fp);
     99  1.1  mrg }
    100  1.1  mrg 
    101  1.1  mrg /* read primitives */
    102  1.1  mrg static void
    103  1.1  mrg skip_line (FILE *fp)
    104  1.1  mrg    /* skips characters until reaching '\n' or EOF; */
    105  1.1  mrg    /* '\n' is skipped as well                      */
    106  1.1  mrg {
    107  1.1  mrg    while (nextchar != EOF && nextchar != '\n')
    108  1.1  mrg      nextchar = getc (fp);
    109  1.1  mrg    if (nextchar != EOF)
    110  1.1  mrg      {
    111  1.1  mrg        line_number ++;
    112  1.1  mrg        nextchar = getc (fp);
    113  1.1  mrg      }
    114  1.1  mrg }
    115  1.1  mrg 
    116  1.1  mrg static void
    117  1.1  mrg skip_whitespace (FILE *fp)
    118  1.1  mrg    /* skips over whitespace if any until reaching EOF */
    119  1.1  mrg    /* or non-whitespace                               */
    120  1.1  mrg {
    121  1.1  mrg    while (isspace (nextchar))
    122  1.1  mrg      {
    123  1.1  mrg        if (nextchar == '\n')
    124  1.1  mrg          line_number ++;
    125  1.1  mrg        nextchar = getc (fp);
    126  1.1  mrg      }
    127  1.1  mrg }
    128  1.1  mrg 
    129  1.1  mrg void
    130  1.1  mrg skip_whitespace_comments (FILE *fp)
    131  1.1  mrg    /* skips over all whitespace and comments, if any */
    132  1.1  mrg {
    133  1.1  mrg    skip_whitespace (fp);
    134  1.1  mrg    while (nextchar == '#') {
    135  1.1  mrg       skip_line (fp);
    136  1.1  mrg       if (nextchar != EOF)
    137  1.1  mrg          skip_whitespace (fp);
    138  1.1  mrg    }
    139  1.1  mrg }
    140  1.1  mrg 
    141  1.1  mrg 
    142  1.1  mrg size_t
    143  1.1  mrg read_string (FILE *fp, char **buffer_ptr, size_t buffer_length, const char *name)
    144  1.1  mrg {
    145  1.1  mrg   size_t pos;
    146  1.1  mrg   char *buffer;
    147  1.1  mrg 
    148  1.1  mrg   pos = 0;
    149  1.1  mrg   buffer = *buffer_ptr;
    150  1.1  mrg 
    151  1.1  mrg   if (nextchar == '"')
    152  1.1  mrg     nextchar = getc (fp);
    153  1.1  mrg   else
    154  1.1  mrg     goto error;
    155  1.1  mrg 
    156  1.1  mrg   while (nextchar != EOF && nextchar != '"')
    157  1.1  mrg     {
    158  1.1  mrg       if (nextchar == '\n')
    159  1.1  mrg         line_number ++;
    160  1.1  mrg       if (pos + 1 > buffer_length)
    161  1.1  mrg         {
    162  1.1  mrg           buffer = (char *) realloc (buffer, 2 * buffer_length);
    163  1.1  mrg           if (buffer == NULL)
    164  1.1  mrg             {
    165  1.1  mrg               printf ("Cannot allocate memory\n");
    166  1.1  mrg               exit (1);
    167  1.1  mrg             }
    168  1.1  mrg           buffer_length *= 2;
    169  1.1  mrg         }
    170  1.1  mrg       buffer[pos++] = (char) nextchar;
    171  1.1  mrg       nextchar = getc (fp);
    172  1.1  mrg     }
    173  1.1  mrg 
    174  1.1  mrg   if (nextchar != '"')
    175  1.1  mrg     goto error;
    176  1.1  mrg 
    177  1.1  mrg   if (pos + 1 > buffer_length)
    178  1.1  mrg     {
    179  1.1  mrg       buffer = (char *) realloc (buffer, buffer_length + 1);
    180  1.1  mrg       if (buffer == NULL)
    181  1.1  mrg         {
    182  1.1  mrg           printf ("Cannot allocate memory\n");
    183  1.1  mrg           exit (1);
    184  1.1  mrg         }
    185  1.1  mrg       buffer_length *= 2;
    186  1.1  mrg     }
    187  1.1  mrg   buffer[pos] = '\0';
    188  1.1  mrg 
    189  1.1  mrg   nextchar = getc (fp);
    190  1.1  mrg   skip_whitespace_comments (fp);
    191  1.1  mrg 
    192  1.1  mrg   *buffer_ptr = buffer;
    193  1.1  mrg 
    194  1.1  mrg   return buffer_length;
    195  1.1  mrg 
    196  1.1  mrg  error:
    197  1.1  mrg   printf ("Error: Unable to read %s in file '%s' line '%lu'\n",
    198  1.1  mrg           name, pathname, line_number);
    199  1.1  mrg   exit (1);
    200  1.1  mrg }
    201  1.1  mrg 
    202  1.1  mrg /* All following read routines skip over whitespace and comments; */
    203  1.1  mrg /* so after calling them, nextchar is either EOF or the beginning */
    204  1.1  mrg /* of a non-comment token.                                        */
    205  1.1  mrg void
    206  1.1  mrg read_ternary (FILE *fp, int* ternary)
    207  1.1  mrg {
    208  1.1  mrg   switch (nextchar)
    209  1.1  mrg     {
    210  1.1  mrg     case '!':
    211  1.1  mrg       *ternary = TERNARY_ERROR;
    212  1.1  mrg       break;
    213  1.1  mrg     case '?':
    214  1.1  mrg       *ternary = TERNARY_NOT_CHECKED;
    215  1.1  mrg       break;
    216  1.1  mrg     case '+':
    217  1.1  mrg       *ternary = +1;
    218  1.1  mrg       break;
    219  1.1  mrg     case '0':
    220  1.1  mrg       *ternary = 0;
    221  1.1  mrg       break;
    222  1.1  mrg     case '-':
    223  1.1  mrg       *ternary = -1;
    224  1.1  mrg       break;
    225  1.1  mrg     default:
    226  1.1  mrg       printf ("Error: Unexpected ternary value '%c' in file '%s' line %lu\n",
    227  1.1  mrg               nextchar, pathname, line_number);
    228  1.1  mrg       exit (1);
    229  1.1  mrg     }
    230  1.1  mrg 
    231  1.1  mrg   nextchar = getc (fp);
    232  1.1  mrg   skip_whitespace_comments (fp);
    233  1.1  mrg }
    234  1.1  mrg 
    235  1.1  mrg void
    236  1.1  mrg read_mpfr_rounding_mode (FILE *fp, mpfr_rnd_t* rnd)
    237  1.1  mrg {
    238  1.1  mrg   switch (nextchar)
    239  1.1  mrg     {
    240  1.1  mrg     case 'n': case 'N':
    241  1.1  mrg       *rnd = GMP_RNDN;
    242  1.1  mrg       break;
    243  1.1  mrg     case 'z': case 'Z':
    244  1.1  mrg       *rnd = GMP_RNDZ;
    245  1.1  mrg       break;
    246  1.1  mrg     case 'u': case 'U':
    247  1.1  mrg       *rnd = GMP_RNDU;
    248  1.1  mrg       break;
    249  1.1  mrg     case 'd': case 'D':
    250  1.1  mrg       *rnd = GMP_RNDD;
    251  1.1  mrg       break;
    252  1.1  mrg     default:
    253  1.1  mrg       printf ("Error: Unexpected rounding mode '%c' in file '%s' line %lu\n",
    254  1.1  mrg               nextchar, pathname, line_number);
    255  1.1  mrg       exit (1);
    256  1.1  mrg     }
    257  1.1  mrg 
    258  1.1  mrg     nextchar = getc (fp);
    259  1.1  mrg     if (nextchar != EOF && !isspace (nextchar)) {
    260  1.1  mrg       printf ("Error: Rounding mode not followed by white space in file "
    261  1.1  mrg               "'%s' line %lu\n",
    262  1.1  mrg               pathname, line_number);
    263  1.1  mrg       exit (1);
    264  1.1  mrg     }
    265  1.1  mrg     skip_whitespace_comments (fp);
    266  1.1  mrg }
    267  1.1  mrg 
    268  1.1  mrg void
    269  1.1  mrg read_mpc_rounding_mode (FILE *fp, mpc_rnd_t* rnd)
    270  1.1  mrg {
    271  1.1  mrg    mpfr_rnd_t re, im;
    272  1.1  mrg    read_mpfr_rounding_mode (fp, &re);
    273  1.1  mrg    read_mpfr_rounding_mode (fp, &im);
    274  1.1  mrg    *rnd = MPC_RND (re, im);
    275  1.1  mrg }
    276  1.1  mrg 
    277  1.1  mrg void
    278  1.1  mrg read_int (FILE *fp, int *nread, const char *name)
    279  1.1  mrg {
    280  1.1  mrg   int n = 0;
    281  1.1  mrg 
    282  1.1  mrg   if (nextchar == EOF)
    283  1.1  mrg     {
    284  1.1  mrg       printf ("Error: Unexpected EOF when reading int "
    285  1.1  mrg               "in file '%s' line %lu\n",
    286  1.1  mrg               pathname, line_number);
    287  1.1  mrg       exit (1);
    288  1.1  mrg     }
    289  1.1  mrg   ungetc (nextchar, fp);
    290  1.1  mrg   n = fscanf (fp, "%i", nread);
    291  1.1  mrg   if (ferror (fp) || n == 0 || n == EOF)
    292  1.1  mrg     {
    293  1.1  mrg       printf ("Error: Cannot read %s in file '%s' line %lu\n",
    294  1.1  mrg               name, pathname, line_number);
    295  1.1  mrg       exit (1);
    296  1.1  mrg     }
    297  1.1  mrg   nextchar = getc (fp);
    298  1.1  mrg   skip_whitespace_comments (fp);
    299  1.1  mrg }
    300  1.1  mrg 
    301  1.1  mrg static void
    302  1.1  mrg read_uint (FILE *fp, unsigned long int *ui)
    303  1.1  mrg {
    304  1.1  mrg   int n = 0;
    305  1.1  mrg 
    306  1.1  mrg   if (nextchar == EOF)
    307  1.1  mrg     {
    308  1.1  mrg       printf ("Error: Unexpected EOF when reading uint "
    309  1.1  mrg               "in file '%s' line %lu\n",
    310  1.1  mrg               pathname, line_number);
    311  1.1  mrg       exit (1);
    312  1.1  mrg     }
    313  1.1  mrg   ungetc (nextchar, fp);
    314  1.1  mrg   n = fscanf (fp, "%lu", ui);
    315  1.1  mrg   if (ferror (fp) || n == 0 || n == EOF)
    316  1.1  mrg     {
    317  1.1  mrg       printf ("Error: Cannot read uint in file '%s' line %lu\n",
    318  1.1  mrg               pathname, line_number);
    319  1.1  mrg       exit (1);
    320  1.1  mrg     }
    321  1.1  mrg   nextchar = getc (fp);
    322  1.1  mrg   skip_whitespace_comments (fp);
    323  1.1  mrg }
    324  1.1  mrg 
    325  1.1  mrg static void
    326  1.1  mrg read_sint (FILE *fp, long int *si)
    327  1.1  mrg {
    328  1.1  mrg   int n = 0;
    329  1.1  mrg 
    330  1.1  mrg   if (nextchar == EOF)
    331  1.1  mrg     {
    332  1.1  mrg       printf ("Error: Unexpected EOF when reading sint "
    333  1.1  mrg               "in file '%s' line %lu\n",
    334  1.1  mrg               pathname, line_number);
    335  1.1  mrg       exit (1);
    336  1.1  mrg     }
    337  1.1  mrg   ungetc (nextchar, fp);
    338  1.1  mrg   n = fscanf (fp, "%li", si);
    339  1.1  mrg   if (ferror (fp) || n == 0 || n == EOF)
    340  1.1  mrg     {
    341  1.1  mrg       printf ("Error: Cannot read sint in file '%s' line %lu\n",
    342  1.1  mrg               pathname, line_number);
    343  1.1  mrg       exit (1);
    344  1.1  mrg     }
    345  1.1  mrg   nextchar = getc (fp);
    346  1.1  mrg   skip_whitespace_comments (fp);
    347  1.1  mrg }
    348  1.1  mrg 
    349  1.1  mrg mpfr_prec_t
    350  1.1  mrg read_mpfr_prec (FILE *fp)
    351  1.1  mrg {
    352  1.1  mrg    unsigned long prec;
    353  1.1  mrg    int n;
    354  1.1  mrg 
    355  1.1  mrg    if (nextchar == EOF) {
    356  1.1  mrg       printf ("Error: Unexpected EOF when reading mpfr precision "
    357  1.1  mrg               "in file '%s' line %lu\n",
    358  1.1  mrg               pathname, line_number);
    359  1.1  mrg       exit (1);
    360  1.1  mrg    }
    361  1.1  mrg    ungetc (nextchar, fp);
    362  1.1  mrg    n = fscanf (fp, "%lu", &prec);
    363  1.1  mrg    if (ferror (fp)) /* then also n == EOF */
    364  1.1  mrg       perror ("Error when reading mpfr precision");
    365  1.1  mrg    if (n == 0 || n == EOF || prec < MPFR_PREC_MIN || prec > MPFR_PREC_MAX) {
    366  1.1  mrg       printf ("Error: Impossible mpfr precision in file '%s' line %lu\n",
    367  1.1  mrg               pathname, line_number);
    368  1.1  mrg       exit (1);
    369  1.1  mrg    }
    370  1.1  mrg    nextchar = getc (fp);
    371  1.1  mrg    skip_whitespace_comments (fp);
    372  1.1  mrg    return (mpfr_prec_t) prec;
    373  1.1  mrg }
    374  1.1  mrg 
    375  1.1  mrg static void
    376  1.1  mrg read_mpfr_mantissa (FILE *fp, mpfr_ptr x)
    377  1.1  mrg {
    378  1.1  mrg    if (nextchar == EOF) {
    379  1.1  mrg       printf ("Error: Unexpected EOF when reading mpfr mantissa "
    380  1.1  mrg               "in file '%s' line %lu\n",
    381  1.1  mrg               pathname, line_number);
    382  1.1  mrg       exit (1);
    383  1.1  mrg    }
    384  1.1  mrg    ungetc (nextchar, fp);
    385  1.1  mrg    if (mpfr_inp_str (x, fp, 0, GMP_RNDN) == 0) {
    386  1.1  mrg       printf ("Error: Impossible to read mpfr mantissa "
    387  1.1  mrg               "in file '%s' line %lu\n",
    388  1.1  mrg               pathname, line_number);
    389  1.1  mrg       exit (1);
    390  1.1  mrg    }
    391  1.1  mrg    nextchar = getc (fp);
    392  1.1  mrg    skip_whitespace_comments (fp);
    393  1.1  mrg }
    394  1.1  mrg 
    395  1.1  mrg void
    396  1.1  mrg read_mpfr (FILE *fp, mpfr_ptr x, int *known_sign)
    397  1.1  mrg {
    398  1.1  mrg    int sign;
    399  1.1  mrg    mpfr_set_prec (x, read_mpfr_prec (fp));
    400  1.1  mrg    sign = nextchar;
    401  1.1  mrg    read_mpfr_mantissa (fp, x);
    402  1.1  mrg 
    403  1.1  mrg    /* the sign always matters for regular values ('+' is implicit),
    404  1.1  mrg       but when no sign appears before 0 or Inf in the data file, it means
    405  1.1  mrg       that only absolute value must be checked. */
    406  1.1  mrg    if (known_sign != NULL)
    407  1.1  mrg      *known_sign =
    408  1.1  mrg        (!mpfr_zero_p (x) && !mpfr_inf_p (x))
    409  1.1  mrg        || sign == '+' || sign == '-';
    410  1.1  mrg }
    411  1.1  mrg 
    412  1.1  mrg void
    413  1.1  mrg read_mpc (FILE *fp, mpc_ptr z, known_signs_t *ks)
    414  1.1  mrg {
    415  1.1  mrg   read_mpfr (fp, mpc_realref (z), ks == NULL ? NULL : &ks->re);
    416  1.1  mrg   read_mpfr (fp, mpc_imagref (z), ks == NULL ? NULL : &ks->im);
    417  1.1  mrg }
    418  1.1  mrg 
    419  1.1  mrg static void
    420  1.1  mrg check_compatible (int inex, mpfr_t expected, mpfr_rnd_t rnd, const char *s)
    421  1.1  mrg {
    422  1.1  mrg   if ((rnd == GMP_RNDU && inex == -1) ||
    423  1.1  mrg       (rnd == GMP_RNDD && inex == +1) ||
    424  1.1  mrg       (rnd == GMP_RNDZ && !mpfr_signbit (expected) && inex == +1) ||
    425  1.1  mrg       (rnd == GMP_RNDZ && mpfr_signbit (expected) && inex == -1))
    426  1.1  mrg     {
    427  1.1  mrg       if (s != NULL)
    428  1.1  mrg         printf ("Incompatible ternary value '%c' (%s part) in file '%s' line %lu\n",
    429  1.1  mrg               (inex == 1) ? '+' : '-', s, pathname, test_line_number);
    430  1.1  mrg       else
    431  1.1  mrg         printf ("Incompatible ternary value '%c' in file '%s' line %lu\n",
    432  1.1  mrg               (inex == 1) ? '+' : '-', pathname, test_line_number);
    433  1.1  mrg     }
    434  1.1  mrg }
    435  1.1  mrg 
    436  1.1  mrg /* read lines of data */
    437  1.1  mrg static void
    438  1.1  mrg read_cc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
    439  1.1  mrg          known_signs_t *signs, mpc_ptr op, mpc_rnd_t *rnd)
    440  1.1  mrg {
    441  1.1  mrg   test_line_number = line_number;
    442  1.1  mrg   read_ternary (fp, inex_re);
    443  1.1  mrg   read_ternary (fp, inex_im);
    444  1.1  mrg   read_mpc (fp, expected, signs);
    445  1.1  mrg   read_mpc (fp, op, NULL);
    446  1.1  mrg   read_mpc_rounding_mode (fp, rnd);
    447  1.1  mrg   check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
    448  1.1  mrg   check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
    449  1.1  mrg }
    450  1.1  mrg 
    451  1.1  mrg static void
    452  1.1  mrg read_fc (FILE *fp, int *inex, mpfr_ptr expected, int *sign, mpc_ptr op,
    453  1.1  mrg          mpfr_rnd_t *rnd)
    454  1.1  mrg {
    455  1.1  mrg   test_line_number = line_number;
    456  1.1  mrg   read_ternary (fp, inex);
    457  1.1  mrg   read_mpfr (fp, expected, sign);
    458  1.1  mrg   read_mpc (fp, op, NULL);
    459  1.1  mrg   read_mpfr_rounding_mode (fp, rnd);
    460  1.1  mrg   check_compatible (*inex, expected, *rnd, NULL);
    461  1.1  mrg }
    462  1.1  mrg 
    463  1.1  mrg static void
    464  1.1  mrg read_ccc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
    465  1.1  mrg           known_signs_t *signs, mpc_ptr op1, mpc_ptr op2, mpc_rnd_t *rnd)
    466  1.1  mrg {
    467  1.1  mrg   test_line_number = line_number;
    468  1.1  mrg   read_ternary (fp, inex_re);
    469  1.1  mrg   read_ternary (fp, inex_im);
    470  1.1  mrg   read_mpc (fp, expected, signs);
    471  1.1  mrg   read_mpc (fp, op1, NULL);
    472  1.1  mrg   read_mpc (fp, op2, NULL);
    473  1.1  mrg   read_mpc_rounding_mode (fp, rnd);
    474  1.1  mrg   check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
    475  1.1  mrg   check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
    476  1.1  mrg }
    477  1.1  mrg 
    478  1.1  mrg /* read lines of data for function with three mpc_t inputs and one mpc_t
    479  1.1  mrg    output like mpc_fma */
    480  1.1  mrg static void
    481  1.1  mrg read_cccc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
    482  1.1  mrg 	   known_signs_t *signs, mpc_ptr op1, mpc_ptr op2, mpc_ptr op3,
    483  1.1  mrg 	   mpc_rnd_t *rnd)
    484  1.1  mrg {
    485  1.1  mrg   test_line_number = line_number;
    486  1.1  mrg   read_ternary (fp, inex_re);
    487  1.1  mrg   read_ternary (fp, inex_im);
    488  1.1  mrg   read_mpc (fp, expected, signs);
    489  1.1  mrg   read_mpc (fp, op1, NULL);
    490  1.1  mrg   read_mpc (fp, op2, NULL);
    491  1.1  mrg   read_mpc (fp, op3, NULL);
    492  1.1  mrg   read_mpc_rounding_mode (fp, rnd);
    493  1.1  mrg   check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
    494  1.1  mrg   check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
    495  1.1  mrg }
    496  1.1  mrg 
    497  1.1  mrg static void
    498  1.1  mrg read_cfc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
    499  1.1  mrg           known_signs_t *signs, mpfr_ptr op1, mpc_ptr op2, mpc_rnd_t *rnd)
    500  1.1  mrg {
    501  1.1  mrg   test_line_number = line_number;
    502  1.1  mrg   read_ternary (fp, inex_re);
    503  1.1  mrg   read_ternary (fp, inex_im);
    504  1.1  mrg   read_mpc (fp, expected, signs);
    505  1.1  mrg   read_mpfr (fp, op1, NULL);
    506  1.1  mrg   read_mpc (fp, op2, NULL);
    507  1.1  mrg   read_mpc_rounding_mode (fp, rnd);
    508  1.1  mrg   check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
    509  1.1  mrg   check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
    510  1.1  mrg }
    511  1.1  mrg 
    512  1.1  mrg static void
    513  1.1  mrg read_ccf (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
    514  1.1  mrg           known_signs_t *signs, mpc_ptr op1, mpfr_ptr op2, mpc_rnd_t *rnd)
    515  1.1  mrg {
    516  1.1  mrg   test_line_number = line_number;
    517  1.1  mrg   read_ternary (fp, inex_re);
    518  1.1  mrg   read_ternary (fp, inex_im);
    519  1.1  mrg   read_mpc (fp, expected, signs);
    520  1.1  mrg   read_mpc (fp, op1, NULL);
    521  1.1  mrg   read_mpfr (fp, op2, NULL);
    522  1.1  mrg   read_mpc_rounding_mode (fp, rnd);
    523  1.1  mrg   check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
    524  1.1  mrg   check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
    525  1.1  mrg }
    526  1.1  mrg 
    527  1.1  mrg static void
    528  1.1  mrg read_ccu (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
    529  1.1  mrg           known_signs_t *signs, mpc_ptr op1, unsigned long int *op2, mpc_rnd_t *rnd)
    530  1.1  mrg {
    531  1.1  mrg   test_line_number = line_number;
    532  1.1  mrg   read_ternary (fp, inex_re);
    533  1.1  mrg   read_ternary (fp, inex_im);
    534  1.1  mrg   read_mpc (fp, expected, signs);
    535  1.1  mrg   read_mpc (fp, op1, NULL);
    536  1.1  mrg   read_uint (fp, op2);
    537  1.1  mrg   read_mpc_rounding_mode (fp, rnd);
    538  1.1  mrg   check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
    539  1.1  mrg   check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
    540  1.1  mrg }
    541  1.1  mrg 
    542  1.1  mrg static void
    543  1.1  mrg read_ccs (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected,
    544  1.1  mrg           known_signs_t *signs, mpc_ptr op1, long int *op2, mpc_rnd_t *rnd)
    545  1.1  mrg {
    546  1.1  mrg   test_line_number = line_number;
    547  1.1  mrg   read_ternary (fp, inex_re);
    548  1.1  mrg   read_ternary (fp, inex_im);
    549  1.1  mrg   read_mpc (fp, expected, signs);
    550  1.1  mrg   read_mpc (fp, op1, NULL);
    551  1.1  mrg   read_sint (fp, op2);
    552  1.1  mrg   read_mpc_rounding_mode (fp, rnd);
    553  1.1  mrg   check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real");
    554  1.1  mrg   check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag");
    555  1.1  mrg }
    556  1.1  mrg 
    557  1.1  mrg /* set MPFR flags to random values */
    558  1.1  mrg static void
    559  1.1  mrg set_mpfr_flags (int counter)
    560  1.1  mrg {
    561  1.1  mrg   if (counter & 1)
    562  1.1  mrg     mpfr_set_underflow ();
    563  1.1  mrg   else
    564  1.1  mrg     mpfr_clear_underflow ();
    565  1.1  mrg   if (counter & 2)
    566  1.1  mrg     mpfr_set_overflow ();
    567  1.1  mrg   else
    568  1.1  mrg     mpfr_clear_overflow ();
    569  1.1  mrg   /* the divide-by-0 flag was added in MPFR 3.1.0 */
    570  1.1  mrg #ifdef mpfr_set_divby0
    571  1.1  mrg   if (counter & 4)
    572  1.1  mrg     mpfr_set_divby0 ();
    573  1.1  mrg   else
    574  1.1  mrg     mpfr_clear_divby0 ();
    575  1.1  mrg #endif
    576  1.1  mrg   if (counter & 8)
    577  1.1  mrg     mpfr_set_nanflag ();
    578  1.1  mrg   else
    579  1.1  mrg     mpfr_clear_nanflag ();
    580  1.1  mrg   if (counter & 16)
    581  1.1  mrg     mpfr_set_inexflag ();
    582  1.1  mrg   else
    583  1.1  mrg     mpfr_clear_inexflag ();
    584  1.1  mrg   if (counter & 32)
    585  1.1  mrg     mpfr_set_erangeflag ();
    586  1.1  mrg   else
    587  1.1  mrg     mpfr_clear_erangeflag ();
    588  1.1  mrg }
    589  1.1  mrg 
    590  1.1  mrg /* Check MPFR flags: we allow that some flags are set internally by MPC,
    591  1.1  mrg    for example if MPC does internal computations (using MPFR) which yield
    592  1.1  mrg    an overflow, even if the final MPC result fits in the exponent range.
    593  1.1  mrg    However we don't allow MPC to *clear* the MPFR flags */
    594  1.1  mrg static void
    595  1.1  mrg check_mpfr_flags (int counter)
    596  1.1  mrg {
    597  1.1  mrg   int old, neu;
    598  1.1  mrg 
    599  1.1  mrg   old = (counter & 1) != 0;
    600  1.1  mrg   neu = mpfr_underflow_p () != 0;
    601  1.1  mrg   if (old && (neu == 0))
    602  1.1  mrg     {
    603  1.1  mrg       printf ("Error, underflow flag has been modified from %d to %d\n",
    604  1.1  mrg               old, neu);
    605  1.1  mrg       exit (1);
    606  1.1  mrg     }
    607  1.1  mrg   old = (counter & 2) != 0;
    608  1.1  mrg   neu = mpfr_overflow_p () != 0;
    609  1.1  mrg   if (old && (neu == 0))
    610  1.1  mrg     {
    611  1.1  mrg       printf ("Error, overflow flag has been modified from %d to %d\n",
    612  1.1  mrg               old, neu);
    613  1.1  mrg       exit (1);
    614  1.1  mrg     }
    615  1.1  mrg #ifdef mpfr_divby0_p
    616  1.1  mrg   old = (counter & 4) != 0;
    617  1.1  mrg   neu = mpfr_divby0_p () != 0;
    618  1.1  mrg   if (old && (neu == 0))
    619  1.1  mrg     {
    620  1.1  mrg       printf ("Error, divby0 flag has been modified from %d to %d\n",
    621  1.1  mrg               old, neu);
    622  1.1  mrg       exit (1);
    623  1.1  mrg     }
    624  1.1  mrg #endif
    625  1.1  mrg   old = (counter & 8) != 0;
    626  1.1  mrg   neu = mpfr_nanflag_p () != 0;
    627  1.1  mrg   if (old && (neu == 0))
    628  1.1  mrg     {
    629  1.1  mrg       printf ("Error, nanflag flag has been modified from %d to %d\n",
    630  1.1  mrg               old, neu);
    631  1.1  mrg       exit (1);
    632  1.1  mrg     }
    633  1.1  mrg   old = (counter & 16) != 0;
    634  1.1  mrg   neu = mpfr_inexflag_p () != 0;
    635  1.1  mrg   if (old && (neu == 0))
    636  1.1  mrg     {
    637  1.1  mrg       printf ("Error, inexflag flag has been modified from %d to %d\n",
    638  1.1  mrg               old, neu);
    639  1.1  mrg       exit (1);
    640  1.1  mrg     }
    641  1.1  mrg   old = (counter & 32) != 0;
    642  1.1  mrg   neu = mpfr_erangeflag_p () != 0;
    643  1.1  mrg   if (old && (neu == 0))
    644  1.1  mrg     {
    645  1.1  mrg       printf ("Error, erangeflag flag has been modified from %d to %d\n",
    646  1.1  mrg               old, neu);
    647  1.1  mrg       exit (1);
    648  1.1  mrg     }
    649  1.1  mrg }
    650  1.1  mrg 
    651  1.1  mrg /* data_check (function, data_file_name) checks function results against
    652  1.1  mrg  precomputed data in a file.*/
    653  1.1  mrg void
    654  1.1  mrg data_check (mpc_function function, const char *file_name)
    655  1.1  mrg {
    656  1.1  mrg   FILE *fp;
    657  1.1  mrg 
    658  1.1  mrg   int inex_re;
    659  1.1  mrg   mpfr_t x1, x2;
    660  1.1  mrg   mpfr_rnd_t mpfr_rnd = GMP_RNDN;
    661  1.1  mrg   int sign_real;
    662  1.1  mrg 
    663  1.1  mrg   int inex_im;
    664  1.1  mrg   mpc_t z1, z2, z3, z4, z5;
    665  1.1  mrg   mpc_rnd_t rnd = MPC_RNDNN;
    666  1.1  mrg 
    667  1.1  mrg   unsigned long int ui;
    668  1.1  mrg   long int si;
    669  1.1  mrg 
    670  1.1  mrg   known_signs_t signs;
    671  1.1  mrg   int inex = 0;
    672  1.1  mrg 
    673  1.1  mrg   static int rand_counter = 0;
    674  1.1  mrg 
    675  1.1  mrg   fp = open_data_file (file_name);
    676  1.1  mrg 
    677  1.1  mrg   /* 1. init needed variables */
    678  1.1  mrg   mpc_init2 (z1, 2);
    679  1.1  mrg   switch (function.type)
    680  1.1  mrg     {
    681  1.1  mrg     case FC:
    682  1.1  mrg       mpfr_init (x1);
    683  1.1  mrg       mpfr_init (x2);
    684  1.1  mrg       break;
    685  1.1  mrg     case CC: case CCU: case CCS:
    686  1.1  mrg       mpc_init2 (z2, 2);
    687  1.1  mrg       mpc_init2 (z3, 2);
    688  1.1  mrg       break;
    689  1.1  mrg     case C_CC:
    690  1.1  mrg       mpc_init2 (z2, 2);
    691  1.1  mrg       mpc_init2 (z3, 2);
    692  1.1  mrg       mpc_init2 (z4, 2);
    693  1.1  mrg       break;
    694  1.1  mrg     case CCCC:
    695  1.1  mrg       mpc_init2 (z2, 2);
    696  1.1  mrg       mpc_init2 (z3, 2);
    697  1.1  mrg       mpc_init2 (z4, 2);
    698  1.1  mrg       mpc_init2 (z5, 2);
    699  1.1  mrg       break;
    700  1.1  mrg     case CFC: case CCF:
    701  1.1  mrg       mpfr_init (x1);
    702  1.1  mrg       mpc_init2 (z2, 2);
    703  1.1  mrg       mpc_init2 (z3, 2);
    704  1.1  mrg       break;
    705  1.1  mrg     default:
    706  1.1  mrg       ;
    707  1.1  mrg     }
    708  1.1  mrg 
    709  1.1  mrg   /* 2. read data file */
    710  1.1  mrg   line_number = 1;
    711  1.1  mrg   nextchar = getc (fp);
    712  1.1  mrg   skip_whitespace_comments (fp);
    713  1.1  mrg   while (nextchar != EOF) {
    714  1.1  mrg       set_mpfr_flags (rand_counter);
    715  1.1  mrg 
    716  1.1  mrg       /* for each kind of function prototype: */
    717  1.1  mrg       /* 3.1 read a line of data: expected result, parameters, rounding mode */
    718  1.1  mrg       /* 3.2 compute function at the same precision as the expected result */
    719  1.1  mrg       /* 3.3 compare this result with the expected one */
    720  1.1  mrg       switch (function.type)
    721  1.1  mrg         {
    722  1.1  mrg         case FC: /* example mpc_norm */
    723  1.1  mrg           read_fc (fp, &inex_re, x1, &sign_real, z1, &mpfr_rnd);
    724  1.1  mrg           mpfr_set_prec (x2, mpfr_get_prec (x1));
    725  1.1  mrg           inex = function.pointer.FC (x2, z1, mpfr_rnd);
    726  1.1  mrg           if ((inex_re != TERNARY_NOT_CHECKED && inex_re != inex)
    727  1.1  mrg               || !same_mpfr_value (x1, x2, sign_real))
    728  1.1  mrg             {
    729  1.1  mrg               mpfr_t got, expected;
    730  1.1  mrg               mpc_t op;
    731  1.1  mrg               op[0] = z1[0];
    732  1.1  mrg               got[0] = x2[0];
    733  1.1  mrg               expected[0] = x1[0];
    734  1.1  mrg               printf ("%s(op) failed (%s:%lu)\nwith rounding mode %s\n",
    735  1.1  mrg                       function.name, file_name, test_line_number,
    736  1.1  mrg                       mpfr_rnd_mode[mpfr_rnd]);
    737  1.1  mrg               if (inex_re != TERNARY_NOT_CHECKED && inex_re != inex)
    738  1.1  mrg                 printf("ternary value: got %s, expected %s\n",
    739  1.1  mrg                        MPFR_INEX_STR (inex), MPFR_INEX_STR (inex_re));
    740  1.1  mrg               MPC_OUT (op);
    741  1.1  mrg               printf ("     ");
    742  1.1  mrg               MPFR_OUT (got);
    743  1.1  mrg               MPFR_OUT (expected);
    744  1.1  mrg 
    745  1.1  mrg               exit (1);
    746  1.1  mrg             }
    747  1.1  mrg           break;
    748  1.1  mrg 
    749  1.1  mrg         case CC: /* example mpc_log */
    750  1.1  mrg           read_cc (fp, &inex_re, &inex_im, z1, &signs, z2, &rnd);
    751  1.1  mrg           mpfr_set_prec (mpc_realref (z3), MPC_PREC_RE (z1));
    752  1.1  mrg           mpfr_set_prec (mpc_imagref (z3), MPC_PREC_IM (z1));
    753  1.1  mrg           inex = function.pointer.CC (z3, z2, rnd);
    754  1.1  mrg           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
    755  1.1  mrg               || !same_mpc_value (z3, z1, signs))
    756  1.1  mrg             {
    757  1.1  mrg               mpc_t op, got, expected; /* display sensible variable names */
    758  1.1  mrg               op[0] = z2[0];
    759  1.1  mrg               expected[0]= z1[0];
    760  1.1  mrg               got[0] = z3[0];
    761  1.1  mrg               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
    762  1.1  mrg                       function.name, test_line_number, rnd_mode[rnd]);
    763  1.1  mrg               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
    764  1.1  mrg                 printf("ternary value: got %s, expected (%s, %s)\n",
    765  1.1  mrg                        MPC_INEX_STR (inex),
    766  1.1  mrg                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
    767  1.1  mrg               MPC_OUT (op);
    768  1.1  mrg               printf ("     ");
    769  1.1  mrg               MPC_OUT (got);
    770  1.1  mrg               MPC_OUT (expected);
    771  1.1  mrg 
    772  1.1  mrg               exit (1);
    773  1.1  mrg             }
    774  1.1  mrg           break;
    775  1.1  mrg 
    776  1.1  mrg         case C_CC: /* example mpc_mul */
    777  1.1  mrg           read_ccc (fp, &inex_re, &inex_im, z1, &signs, z2, z3, &rnd);
    778  1.1  mrg           mpfr_set_prec (mpc_realref(z4), MPC_PREC_RE (z1));
    779  1.1  mrg           mpfr_set_prec (mpc_imagref(z4), MPC_PREC_IM (z1));
    780  1.1  mrg           inex = function.pointer.C_CC (z4, z2, z3, rnd);
    781  1.1  mrg           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
    782  1.1  mrg               || !same_mpc_value (z4, z1, signs))
    783  1.1  mrg             {
    784  1.1  mrg               /* display sensible variable names */
    785  1.1  mrg               mpc_t op1, op2, got, expected;
    786  1.1  mrg               op1[0] = z2[0];
    787  1.1  mrg               op2[0] = z3[0];
    788  1.1  mrg               expected[0]= z1[0];
    789  1.1  mrg               got[0] = z4[0];
    790  1.1  mrg               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
    791  1.1  mrg                       function.name, test_line_number, rnd_mode[rnd]);
    792  1.1  mrg               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
    793  1.1  mrg                 printf("ternary value: got %s, expected (%s, %s)\n",
    794  1.1  mrg                        MPC_INEX_STR (inex),
    795  1.1  mrg                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
    796  1.1  mrg               MPC_OUT (op1);
    797  1.1  mrg               MPC_OUT (op2);
    798  1.1  mrg               printf ("     ");
    799  1.1  mrg               MPC_OUT (got);
    800  1.1  mrg               MPC_OUT (expected);
    801  1.1  mrg 
    802  1.1  mrg               exit (1);
    803  1.1  mrg             }
    804  1.1  mrg           if (function.properties & FUNC_PROP_SYMETRIC)
    805  1.1  mrg             {
    806  1.1  mrg               inex = function.pointer.C_CC (z4, z3, z2, rnd);
    807  1.1  mrg               if (!MPC_INEX_CMP (inex_re, inex_im, inex)
    808  1.1  mrg               || !same_mpc_value (z4, z1, signs))
    809  1.1  mrg                 {
    810  1.1  mrg                   /* display sensible variable names */
    811  1.1  mrg                   mpc_t op1, op2, got, expected;
    812  1.1  mrg                   op1[0] = z3[0];
    813  1.1  mrg                   op2[0] = z2[0];
    814  1.1  mrg                   expected[0]= z1[0];
    815  1.1  mrg                   got[0] = z4[0];
    816  1.1  mrg                   printf ("%s(op) failed (line %lu/symetric test)\n"
    817  1.1  mrg                           "with rounding mode %s\n",
    818  1.1  mrg                           function.name, test_line_number, rnd_mode[rnd]);
    819  1.1  mrg                   if (!MPC_INEX_CMP (inex_re, inex_im, inex))
    820  1.1  mrg                     printf("ternary value: got %s, expected (%s, %s)\n",
    821  1.1  mrg                            MPC_INEX_STR (inex),
    822  1.1  mrg                            MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
    823  1.1  mrg                   MPC_OUT (op1);
    824  1.1  mrg                   MPC_OUT (op2);
    825  1.1  mrg                   printf ("     ");
    826  1.1  mrg                   MPC_OUT (got);
    827  1.1  mrg                   MPC_OUT (expected);
    828  1.1  mrg 
    829  1.1  mrg                   exit (1);
    830  1.1  mrg                 }
    831  1.1  mrg             }
    832  1.1  mrg           break;
    833  1.1  mrg 
    834  1.1  mrg         case CCCC: /* example mpc_fma */
    835  1.1  mrg           read_cccc (fp, &inex_re, &inex_im, z1, &signs, z2, z3, z4, &rnd);
    836  1.1  mrg 	  /* z1 is the expected value, z2, z3, z4 are the inputs, and z5 is
    837  1.1  mrg 	     the computed value */
    838  1.1  mrg           mpfr_set_prec (mpc_realref(z5), MPC_PREC_RE (z1));
    839  1.1  mrg           mpfr_set_prec (mpc_imagref(z5), MPC_PREC_IM (z1));
    840  1.1  mrg           inex = function.pointer.CCCC (z5, z2, z3, z4, rnd);
    841  1.1  mrg           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
    842  1.1  mrg               || !same_mpc_value (z5, z1, signs))
    843  1.1  mrg             {
    844  1.1  mrg               /* display sensible variable names */
    845  1.1  mrg               mpc_t op1, op2, op3, got, expected;
    846  1.1  mrg               op1[0] = z2[0];
    847  1.1  mrg               op2[0] = z3[0];
    848  1.1  mrg               op3[0] = z4[0];
    849  1.1  mrg               expected[0]= z1[0];
    850  1.1  mrg               got[0] = z5[0];
    851  1.1  mrg               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
    852  1.1  mrg                       function.name, test_line_number, rnd_mode[rnd]);
    853  1.1  mrg               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
    854  1.1  mrg                 printf("ternary value: got %s, expected (%s, %s)\n",
    855  1.1  mrg                        MPC_INEX_STR (inex),
    856  1.1  mrg                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
    857  1.1  mrg               MPC_OUT (op1);
    858  1.1  mrg               MPC_OUT (op2);
    859  1.1  mrg               MPC_OUT (op3);
    860  1.1  mrg               printf ("     ");
    861  1.1  mrg               MPC_OUT (got);
    862  1.1  mrg               MPC_OUT (expected);
    863  1.1  mrg 
    864  1.1  mrg               exit (1);
    865  1.1  mrg             }
    866  1.1  mrg           if (function.properties & FUNC_PROP_SYMETRIC)
    867  1.1  mrg             {
    868  1.1  mrg               inex = function.pointer.CCCC (z5, z3, z2, z4, rnd);
    869  1.1  mrg               if (!MPC_INEX_CMP (inex_re, inex_im, inex)
    870  1.1  mrg               || !same_mpc_value (z5, z1, signs))
    871  1.1  mrg                 {
    872  1.1  mrg                   /* display sensible variable names */
    873  1.1  mrg                   mpc_t op1, op2, op3, got, expected;
    874  1.1  mrg                   op1[0] = z3[0];
    875  1.1  mrg                   op2[0] = z2[0];
    876  1.1  mrg 		  op3[0] = z4[0];
    877  1.1  mrg                   expected[0]= z1[0];
    878  1.1  mrg                   got[0] = z5[0];
    879  1.1  mrg                   printf ("%s(op) failed (line %lu/symetric test)\n"
    880  1.1  mrg                           "with rounding mode %s\n",
    881  1.1  mrg                           function.name, test_line_number, rnd_mode[rnd]);
    882  1.1  mrg                   if (!MPC_INEX_CMP (inex_re, inex_im, inex))
    883  1.1  mrg                     printf("ternary value: got %s, expected (%s, %s)\n",
    884  1.1  mrg                            MPC_INEX_STR (inex),
    885  1.1  mrg                            MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
    886  1.1  mrg                   MPC_OUT (op1);
    887  1.1  mrg                   MPC_OUT (op2);
    888  1.1  mrg 		  MPC_OUT (op3);
    889  1.1  mrg                   printf ("     ");
    890  1.1  mrg                   MPC_OUT (got);
    891  1.1  mrg                   MPC_OUT (expected);
    892  1.1  mrg 
    893  1.1  mrg                   exit (1);
    894  1.1  mrg                 }
    895  1.1  mrg             }
    896  1.1  mrg           break;
    897  1.1  mrg 
    898  1.1  mrg         case CFC: /* example mpc_fr_div */
    899  1.1  mrg           read_cfc (fp, &inex_re, &inex_im, z1, &signs, x1, z2, &rnd);
    900  1.1  mrg           mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1));
    901  1.1  mrg           mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1));
    902  1.1  mrg           inex = function.pointer.CFC (z3, x1, z2, rnd);
    903  1.1  mrg           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
    904  1.1  mrg               || !same_mpc_value (z3, z1, signs))
    905  1.1  mrg             {
    906  1.1  mrg               /* display sensible variable names */
    907  1.1  mrg               mpc_t op2, got, expected;
    908  1.1  mrg               mpfr_t op1;
    909  1.1  mrg               op1[0] = x1[0];
    910  1.1  mrg               op2[0] = z2[0];
    911  1.1  mrg               expected[0]= z1[0];
    912  1.1  mrg               got[0] = z3[0];
    913  1.1  mrg               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
    914  1.1  mrg                       function.name, test_line_number, rnd_mode[rnd]);
    915  1.1  mrg               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
    916  1.1  mrg                 printf("ternary value: got %s, expected (%s, %s)\n",
    917  1.1  mrg                        MPC_INEX_STR (inex),
    918  1.1  mrg                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
    919  1.1  mrg               MPFR_OUT (op1);
    920  1.1  mrg               MPC_OUT (op2);
    921  1.1  mrg               printf ("     ");
    922  1.1  mrg               MPC_OUT (got);
    923  1.1  mrg               MPC_OUT (expected);
    924  1.1  mrg 
    925  1.1  mrg               exit (1);
    926  1.1  mrg             }
    927  1.1  mrg           break;
    928  1.1  mrg 
    929  1.1  mrg         case CCF: /* example mpc_mul_fr */
    930  1.1  mrg           read_ccf (fp, &inex_re, &inex_im, z1, &signs, z2, x1, &rnd);
    931  1.1  mrg           mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1));
    932  1.1  mrg           mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1));
    933  1.1  mrg           inex = function.pointer.CCF (z3, z2, x1, rnd);
    934  1.1  mrg           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
    935  1.1  mrg               || !same_mpc_value (z3, z1, signs))
    936  1.1  mrg             {
    937  1.1  mrg               /* display sensible variable names */
    938  1.1  mrg               mpc_t op1, got, expected;
    939  1.1  mrg               mpfr_t op2;
    940  1.1  mrg               op1[0] = z2[0];
    941  1.1  mrg               op2[0] = x1[0];
    942  1.1  mrg               expected[0]= z1[0];
    943  1.1  mrg               got[0] = z3[0];
    944  1.1  mrg               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
    945  1.1  mrg                       function.name, test_line_number, rnd_mode[rnd]);
    946  1.1  mrg               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
    947  1.1  mrg                 printf("ternary value: got %s, expected (%s, %s)\n",
    948  1.1  mrg                        MPC_INEX_STR (inex),
    949  1.1  mrg                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
    950  1.1  mrg               MPC_OUT (op1);
    951  1.1  mrg               MPFR_OUT (op2);
    952  1.1  mrg               printf ("     ");
    953  1.1  mrg               MPC_OUT (got);
    954  1.1  mrg               MPC_OUT (expected);
    955  1.1  mrg 
    956  1.1  mrg               exit (1);
    957  1.1  mrg             }
    958  1.1  mrg           break;
    959  1.1  mrg 
    960  1.1  mrg         case CCU: /* example mpc_pow_ui */
    961  1.1  mrg           read_ccu (fp, &inex_re, &inex_im, z1, &signs, z2, &ui, &rnd);
    962  1.1  mrg           mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1));
    963  1.1  mrg           mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1));
    964  1.1  mrg           inex = function.pointer.CCU (z3, z2, ui, rnd);
    965  1.1  mrg           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
    966  1.1  mrg               || !same_mpc_value (z3, z1, signs))
    967  1.1  mrg             {
    968  1.1  mrg               /* display sensible variable names */
    969  1.1  mrg               mpc_t op1, got, expected;
    970  1.1  mrg               op1[0] = z2[0];
    971  1.1  mrg               expected[0]= z1[0];
    972  1.1  mrg               got[0] = z3[0];
    973  1.1  mrg               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
    974  1.1  mrg                       function.name, test_line_number, rnd_mode[rnd]);
    975  1.1  mrg               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
    976  1.1  mrg                 printf("ternary value: got %s, expected (%s, %s)\n",
    977  1.1  mrg                        MPC_INEX_STR (inex),
    978  1.1  mrg                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
    979  1.1  mrg               MPC_OUT (op1);
    980  1.1  mrg               printf ("op2 %lu\n     ", ui);
    981  1.1  mrg               MPC_OUT (got);
    982  1.1  mrg               MPC_OUT (expected);
    983  1.1  mrg 
    984  1.1  mrg               exit (1);
    985  1.1  mrg             }
    986  1.1  mrg           break;
    987  1.1  mrg 
    988  1.1  mrg         case CCS: /* example mpc_pow_si */
    989  1.1  mrg           read_ccs (fp, &inex_re, &inex_im, z1, &signs, z2, &si, &rnd);
    990  1.1  mrg           mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1));
    991  1.1  mrg           mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1));
    992  1.1  mrg           inex = function.pointer.CCS (z3, z2, si, rnd);
    993  1.1  mrg           if (!MPC_INEX_CMP (inex_re, inex_im, inex)
    994  1.1  mrg               || !same_mpc_value (z3, z1, signs))
    995  1.1  mrg             {
    996  1.1  mrg               /* display sensible variable names */
    997  1.1  mrg               mpc_t op1, got, expected;
    998  1.1  mrg               op1[0] = z2[0];
    999  1.1  mrg               expected[0]= z1[0];
   1000  1.1  mrg               got[0] = z3[0];
   1001  1.1  mrg               printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n",
   1002  1.1  mrg                       function.name, test_line_number, rnd_mode[rnd]);
   1003  1.1  mrg               if (!MPC_INEX_CMP (inex_re, inex_im, inex))
   1004  1.1  mrg                 printf("ternary value: got %s, expected (%s, %s)\n",
   1005  1.1  mrg                        MPC_INEX_STR (inex),
   1006  1.1  mrg                        MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im));
   1007  1.1  mrg               MPC_OUT (op1);
   1008  1.1  mrg               printf ("op2 %li\n     ", si);
   1009  1.1  mrg               MPC_OUT (got);
   1010  1.1  mrg               MPC_OUT (expected);
   1011  1.1  mrg 
   1012  1.1  mrg               exit (1);
   1013  1.1  mrg             }
   1014  1.1  mrg           break;
   1015  1.1  mrg 
   1016  1.1  mrg         default:
   1017  1.1  mrg           printf ("Unhandled function prototype %i in 'data_check'\n", function.type);
   1018  1.1  mrg           exit (1);
   1019  1.1  mrg         }
   1020  1.1  mrg 
   1021  1.1  mrg       /* check MPFR flags were not modified */
   1022  1.1  mrg       check_mpfr_flags (rand_counter);
   1023  1.1  mrg       rand_counter ++;
   1024  1.1  mrg     }
   1025  1.1  mrg 
   1026  1.1  mrg   /* 3. Clear used variables */
   1027  1.1  mrg   mpc_clear (z1);
   1028  1.1  mrg   switch (function.type)
   1029  1.1  mrg     {
   1030  1.1  mrg     case FC:
   1031  1.1  mrg       mpfr_clear (x1);
   1032  1.1  mrg       mpfr_clear (x2);
   1033  1.1  mrg       break;
   1034  1.1  mrg     case CC: case CCU: case CCS:
   1035  1.1  mrg       mpc_clear (z2);
   1036  1.1  mrg       mpc_clear (z3);
   1037  1.1  mrg       break;
   1038  1.1  mrg     case C_CC:
   1039  1.1  mrg       mpc_clear (z2);
   1040  1.1  mrg       mpc_clear (z3);
   1041  1.1  mrg       mpc_clear (z4);
   1042  1.1  mrg       break;
   1043  1.1  mrg     case CCCC:
   1044  1.1  mrg       mpc_clear (z2);
   1045  1.1  mrg       mpc_clear (z3);
   1046  1.1  mrg       mpc_clear (z4);
   1047  1.1  mrg       mpc_clear (z5);
   1048  1.1  mrg       break;
   1049  1.1  mrg     case CFC: case CCF:
   1050  1.1  mrg       mpfr_clear (x1);
   1051  1.1  mrg       mpc_clear (z2);
   1052  1.1  mrg       mpc_clear (z3);
   1053  1.1  mrg       break;
   1054  1.1  mrg     default:
   1055  1.1  mrg       ;
   1056  1.1  mrg     }
   1057  1.1  mrg 
   1058  1.1  mrg   close_data_file (fp);
   1059  1.1  mrg }
   1060