1/* mpc-tests.h -- Tests helper functions. 2 3Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA 4 5This file is part of GNU MPC. 6 7GNU MPC is free software; you can redistribute it and/or modify it under 8the terms of the GNU Lesser General Public License as published by the 9Free Software Foundation; either version 3 of the License, or (at your 10option) any later version. 11 12GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15more details. 16 17You should have received a copy of the GNU Lesser General Public License 18along with this program. If not, see http://www.gnu.org/licenses/ . 19*/ 20 21#ifndef __MPC_TESTS_H 22#define __MPC_TESTS_H 23 24#include "config.h" 25#include <stdio.h> 26#include <ctype.h> 27#include <stdlib.h> 28#include "mpc.h" 29 30/* pieces copied from mpc-impl.h */ 31#define MPC_PREC_RE(x) (mpfr_get_prec(mpc_realref(x))) 32#define MPC_PREC_IM(x) (mpfr_get_prec(mpc_imagref(x))) 33#define MPC_MAX_PREC(x) MPC_MAX(MPC_PREC_RE(x), MPC_PREC_IM(x)) 34#define MPC_MAX(h,i) ((h) > (i) ? (h) : (i)) 35 36#define MPC_ASSERT(expr) \ 37 do { \ 38 if (!(expr)) \ 39 { \ 40 fprintf (stderr, "%s:%d: MPC assertion failed: %s\n", \ 41 __FILE__, __LINE__, #expr); \ 42 abort(); \ 43 } \ 44 } while (0) 45 46#if defined (__cplusplus) 47extern "C" { 48#endif 49__MPC_DECLSPEC int mpc_mul_naive (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t); 50__MPC_DECLSPEC int mpc_mul_karatsuba (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t); 51__MPC_DECLSPEC int mpc_fma_naive (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t); 52#if defined (__cplusplus) 53} 54#endif 55/* end pieces copied from mpc-impl.h */ 56 57#define MPC_OUT(x) \ 58do { \ 59 printf (#x "[%lu,%lu]=", (unsigned long int) MPC_PREC_RE (x), \ 60 (unsigned long int) MPC_PREC_IM (x)); \ 61 mpc_out_str (stdout, 2, 0, x, MPC_RNDNN); \ 62 printf ("\n"); \ 63} while (0) 64 65#define MPFR_OUT(x) \ 66do { \ 67 printf (#x "[%lu]=", (unsigned long int) mpfr_get_prec (x)); \ 68 mpfr_out_str (stdout, 2, 0, x, GMP_RNDN); \ 69 printf ("\n"); \ 70} while (0) 71 72 73#define MPC_INEX_STR(inex) \ 74 (inex) == 0 ? "(0, 0)" \ 75 : (inex) == 1 ? "(+1, 0)" \ 76 : (inex) == 2 ? "(-1, 0)" \ 77 : (inex) == 4 ? "(0, +1)" \ 78 : (inex) == 5 ? "(+1, +1)" \ 79 : (inex) == 6 ? "(-1, +1)" \ 80 : (inex) == 8 ? "(0, -1)" \ 81 : (inex) == 9 ? "(+1, -1)" \ 82 : (inex) == 10 ? "(-1, -1)" : "unknown" 83 84#define TEST_FAILED(func,op,got,expected,rnd) \ 85 do { \ 86 printf ("%s(op) failed [rnd=%d]\n with", func, rnd); \ 87 MPC_OUT (op); \ 88 printf (" "); \ 89 MPC_OUT (got); \ 90 MPC_OUT (expected); \ 91 exit (1); \ 92 } while (0) 93 94#define QUOTE(X) NAME(X) 95#define NAME(X) #X 96 97/** RANDOM FUNCTIONS **/ 98/* the 3 following functions handle seed for random numbers. Usage: 99 - add test_start at the beginning of your test function 100 - use test_default_random (or use your random functions with 101 gmp_randstate_t rands) in your tests 102 - add test_end at the end the test function */ 103extern gmp_randstate_t rands; 104 105extern void test_start (void); 106extern void test_end (void); 107extern void test_default_random (mpc_ptr, mp_exp_t, mp_exp_t, unsigned int, unsigned int); 108 109 110/** COMPARISON FUNCTIONS **/ 111/* some sign are unspecified in ISO C99, thus we record in struct known_signs_t 112 whether the sign has to be checked */ 113typedef struct 114{ 115 int re; /* boolean value */ 116 int im; /* boolean value */ 117} known_signs_t; 118 119/* same_mpfr_value returns 1: 120 - if got and ref have the same value and known_sign is true, 121 or 122 - if they have the same absolute value, got = 0 or got = inf, and known_sign is 123 false. 124 returns 0 in other cases. 125 Unlike mpfr_cmp, same_mpfr_value(got, ref, x) return 1 when got and 126 ref are both NaNs. */ 127extern int same_mpfr_value (mpfr_ptr got, mpfr_ptr ref, int known_sign); 128extern int same_mpc_value (mpc_ptr got, mpc_ptr ref, known_signs_t known_signs); 129 130 131/** GENERIC TESTS **/ 132 133typedef int (*CC_func_ptr) (mpc_t, mpc_srcptr, mpc_rnd_t); 134typedef int (*C_CC_func_ptr) (mpc_t, mpc_srcptr, mpc_srcptr, mpc_rnd_t); 135typedef int (*CCCC_func_ptr) (mpc_t, mpc_srcptr, mpc_srcptr, mpc_srcptr, 136 mpc_rnd_t); 137typedef int (*CCU_func_ptr) (mpc_t, mpc_srcptr, unsigned long, mpc_rnd_t); 138typedef int (*CCS_func_ptr) (mpc_t, mpc_srcptr, long, mpc_rnd_t); 139typedef int (*CCI_func_ptr) (mpc_t, mpc_srcptr, int, mpc_rnd_t); 140typedef int (*CCF_func_ptr) (mpc_t, mpc_srcptr, mpfr_srcptr, mpc_rnd_t); 141typedef int (*CFC_func_ptr) (mpc_t, mpfr_srcptr, mpc_srcptr, mpc_rnd_t); 142typedef int (*CUC_func_ptr) (mpc_t, unsigned long, mpc_srcptr, mpc_rnd_t); 143typedef int (*CUUC_func_ptr) (mpc_t, unsigned long, unsigned long, mpc_srcptr, 144 mpc_rnd_t); 145typedef int (*FC_func_ptr) (mpfr_t, mpc_srcptr, mpfr_rnd_t); 146typedef int (*CC_C_func_ptr) (mpc_t, mpc_t, mpc_srcptr, mpc_rnd_t, mpc_rnd_t); 147 148typedef union { 149 FC_func_ptr FC; /* output: mpfr_t, input: mpc_t */ 150 CC_func_ptr CC; /* output: mpc_t, input: mpc_t */ 151 C_CC_func_ptr C_CC; /* output: mpc_t, inputs: (mpc_t, mpc_t) */ 152 CCCC_func_ptr CCCC; /* output: mpc_t, inputs: (mpc_t, mpc_t, mpc_t) */ 153 CCU_func_ptr CCU; /* output: mpc_t, inputs: (mpc_t, unsigned long) */ 154 CCS_func_ptr CCS; /* output: mpc_t, inputs: (mpc_t, long) */ 155 CCI_func_ptr CCI; /* output: mpc_t, inputs: (mpc_t, int) */ 156 CCF_func_ptr CCF; /* output: mpc_t, inputs: (mpc_t, mpfr_t) */ 157 CFC_func_ptr CFC; /* output: mpc_t, inputs: (mpfr_t, mpc_t) */ 158 CUC_func_ptr CUC; /* output: mpc_t, inputs: (unsigned long, mpc_t) */ 159 CUUC_func_ptr CUUC; /* output: mpc_t, inputs: (ulong, ulong, mpc_t) */ 160 CC_C_func_ptr CC_C; /* outputs: (mpc_t, mpc_t), input: mpc_t */ 161} func_ptr; 162 163/* the rounding mode is implicit */ 164typedef enum { 165 FC, /* output: mpfr_t, input: mpc_t */ 166 CC, /* output: mpc_t, input: mpc_t */ 167 C_CC, /* output: mpc_t, inputs: (mpc_t, mpc_t) */ 168 CCCC, /* output: mpc_t, inputs: (mpc_t, mpc_t, mpc_t) */ 169 CCU, /* output: mpc_t, inputs: (mpc_t, unsigned long) */ 170 CCS, /* output: mpc_t, inputs: (mpc_t, long) */ 171 CCI, /* output: mpc_t, inputs: (mpc_t, int) */ 172 CCF, /* output: mpc_t, inputs: (mpc_t, mpfr_t) */ 173 CFC, /* output: mpc_t, inputs: (mpfr_t, mpc_t) */ 174 CUC, /* output: mpc_t, inputs: (unsigned long, mpc_t) */ 175 CUUC, /* output: mpc_t, inputs: (ulong, ulong, mpc_t) */ 176 CC_C /* outputs: (mpc_t, mpc_t), input: mpc_t */ 177} func_type; 178 179/* properties */ 180#define FUNC_PROP_NONE 0 181#define FUNC_PROP_SYMETRIC 1 182 183typedef struct 184{ 185 func_ptr pointer; 186 func_type type; 187 const char * name; 188 int properties; 189} mpc_function; 190 191#define DECL_FUNC(_ftype, _fvar, _func) \ 192 mpc_function _fvar; \ 193 _fvar.pointer._ftype = _func; \ 194 _fvar.type = _ftype; \ 195 _fvar.name = QUOTE (_func); \ 196 _fvar.properties = FUNC_PROP_NONE; 197 198 199/* tgeneric(mpc_function, prec_min, prec_max, step, exp_max) checks rounding 200 with random numbers: 201 - with precision ranging from prec_min to prec_max with an increment of 202 step, 203 - with exponent between -exp_max and exp_max. 204 205 It also checks parameter reuse (it is assumed here that either two mpc_t 206 variables are equal or they are different, in the sense that the real part of 207 one of them cannot be the imaginary part of the other). */ 208void tgeneric (mpc_function, mpfr_prec_t, mpfr_prec_t, mpfr_prec_t, mp_exp_t); 209 210 211/** READ FILE WITH TEST DATA SET **/ 212/* data_check (function, "data_file_name") checks function results against 213 precomputed data in a file.*/ 214extern void data_check (mpc_function, const char *); 215 216extern FILE * open_data_file (const char *file_name); 217extern void close_data_file (FILE *fp); 218 219/* helper file reading functions */ 220extern void skip_whitespace_comments (FILE *fp); 221extern void read_ternary (FILE *fp, int* ternary); 222extern void read_mpfr_rounding_mode (FILE *fp, mpfr_rnd_t* rnd); 223extern void read_mpc_rounding_mode (FILE *fp, mpc_rnd_t* rnd); 224extern mpfr_prec_t read_mpfr_prec (FILE *fp); 225extern void read_int (FILE *fp, int *n, const char *name); 226extern size_t read_string (FILE *fp, char **buffer_ptr, size_t buffer_length, const char *name); 227extern void read_mpfr (FILE *fp, mpfr_ptr x, int *known_sign); 228extern void read_mpc (FILE *fp, mpc_ptr z, known_signs_t *ks); 229 230#define TERNARY_NOT_CHECKED 255 231 /* special value to indicate that the ternary value is not checked */ 232#define TERNARY_ERROR 254 233 /* special value to indicate that an error occurred in an mpc function */ 234 235#endif /* __MPC_TESTS_H */ 236