Blame tests/read_data.c

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