1 /* mpc-tests.h -- Tests helper functions. 2 3 Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2020, 2022 INRIA 4 5 This file is part of GNU MPC. 6 7 GNU MPC is free software; you can redistribute it and/or modify it under 8 the terms of the GNU Lesser General Public License as published by the 9 Free Software Foundation; either version 3 of the License, or (at your 10 option) any later version. 11 12 GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 more details. 16 17 You should have received a copy of the GNU Lesser General Public License 18 along 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 <inttypes.h> /* for the PRIi64 format modifier */ 29 #include "mpc-impl.h" 30 31 /* pieces copied from mpc-impl.h */ 32 #define MPC_PREC_RE(x) (mpfr_get_prec(mpc_realref(x))) 33 #define MPC_PREC_IM(x) (mpfr_get_prec(mpc_imagref(x))) 34 #define MPC_MAX_PREC(x) MPC_MAX(MPC_PREC_RE(x), MPC_PREC_IM(x)) 35 #define MPC_MAX(h,i) ((h) > (i) ? (h) : (i)) 36 37 #define MPC_ASSERT(expr) \ 38 do { \ 39 if (!(expr)) \ 40 { \ 41 fprintf (stderr, "%s:%d: MPC assertion failed: %s\n", \ 42 __FILE__, __LINE__, #expr); \ 43 abort(); \ 44 } \ 45 } while (0) 46 47 #if defined (__cplusplus) 48 extern "C" { 49 #endif 50 __MPC_DECLSPEC int64_t sqrt_int64 (int64_t n); 51 __MPC_DECLSPEC int mpc_mul_naive (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t); 52 __MPC_DECLSPEC int mpc_mul_karatsuba (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t); 53 __MPC_DECLSPEC int mpc_fma_naive (mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t); 54 #if defined (__cplusplus) 55 } 56 #endif 57 /* end pieces copied from mpc-impl.h */ 58 59 #define MPC_OUT(x) \ 60 do { \ 61 printf (#x "[%lu,%lu]=", (unsigned long int) MPC_PREC_RE (x), \ 62 (unsigned long int) MPC_PREC_IM (x)); \ 63 mpc_out_str (stdout, 2, 0, x, MPC_RNDNN); \ 64 printf ("\n"); \ 65 } while (0) 66 67 #define MPFR_OUT(x) \ 68 do { \ 69 printf (#x "[%lu]=", (unsigned long int) mpfr_get_prec (x)); \ 70 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); \ 71 printf ("\n"); \ 72 } while (0) 73 74 75 #define MPC_INEX_STR(inex) \ 76 (inex) == 0 ? "(0, 0)" \ 77 : (inex) == 1 ? "(+1, 0)" \ 78 : (inex) == 2 ? "(-1, 0)" \ 79 : (inex) == 4 ? "(0, +1)" \ 80 : (inex) == 5 ? "(+1, +1)" \ 81 : (inex) == 6 ? "(-1, +1)" \ 82 : (inex) == 8 ? "(0, -1)" \ 83 : (inex) == 9 ? "(+1, -1)" \ 84 : (inex) == 10 ? "(-1, -1)" : "unknown" 85 86 #define TEST_FAILED(func,op,got,expected,rnd) \ 87 do { \ 88 printf ("%s(op) failed [rnd=%d]\n with", func, rnd); \ 89 MPC_OUT (op); \ 90 printf (" "); \ 91 MPC_OUT (got); \ 92 MPC_OUT (expected); \ 93 exit (1); \ 94 } while (0) 95 96 #define QUOTE(X) NAME(X) 97 #define NAME(X) #X 98 99 /** RANDOM FUNCTIONS **/ 100 /* the 3 following functions handle seed for random numbers. Usage: 101 - add test_start at the beginning of your test function 102 - use test_default_random (or use your random functions with 103 gmp_randstate_t rands) in your tests 104 - add test_end at the end the test function */ 105 extern gmp_randstate_t rands; 106 107 extern void test_start (void); 108 extern void test_end (void); 109 extern void test_default_random (mpc_ptr, mpfr_exp_t, mpfr_exp_t, 110 unsigned int, unsigned int); 111 112 void test_random_si (long int *n, unsigned long emax, 113 unsigned int negative_probability); 114 void test_random_d (double *x, unsigned int negative_probability); 115 void test_random_mpfr (mpfr_ptr x, mpfr_exp_t emin, mpfr_exp_t emax, 116 unsigned int negative_probability); 117 void test_random_mpc (mpc_ptr z, mpfr_exp_t emin, mpfr_exp_t emax, 118 unsigned int negative_probability); 119 120 /** COMPARISON FUNCTIONS **/ 121 /* some sign are unspecified in ISO C99, thus we record in struct known_signs_t 122 whether the sign has to be checked */ 123 typedef struct 124 { 125 int re; /* boolean value */ 126 int im; /* boolean value */ 127 } known_signs_t; 128 129 /* same_mpfr_value returns 1: 130 - if got and ref have the same value and known_sign is true, 131 or 132 - if they have the same absolute value, got = 0 or got = inf, and known_sign is 133 false. 134 returns 0 in other cases. 135 Unlike mpfr_cmp, same_mpfr_value(got, ref, x) return 1 when got and 136 ref are both NaNs. */ 137 extern int same_mpfr_value (mpfr_ptr got, mpfr_ptr ref, int known_sign); 138 extern int same_mpc_value (mpc_ptr got, mpc_ptr ref, 139 known_signs_t known_signs); 140 141 /** READ FILE WITH TEST DATA SET **/ 142 extern FILE * open_data_file (const char *file_name); 143 extern void close_data_file (FILE *fp); 144 145 /* helper file reading functions */ 146 extern void skip_whitespace_comments (FILE *fp); 147 extern void read_ternary (FILE *fp, int* ternary); 148 extern void read_mpfr_rounding_mode (FILE *fp, mpfr_rnd_t* rnd); 149 extern void read_mpc_rounding_mode (FILE *fp, mpc_rnd_t* rnd); 150 extern mpfr_prec_t read_mpfr_prec (FILE *fp); 151 extern void read_int (FILE *fp, int *n, const char *name); 152 extern size_t read_string (FILE *fp, char **buffer_ptr, 153 size_t buffer_length, const char *name); 154 extern void read_mpfr (FILE *fp, mpfr_ptr x, int *known_sign); 155 extern void read_mpc (FILE *fp, mpc_ptr z, known_signs_t *ks); 156 157 void set_mpfr_flags (int counter); 158 void check_mpfr_flags (int counter); 159 160 /* 161 function descriptions 162 */ 163 164 /* type for return, output and input parameters */ 165 typedef enum { 166 NATIVE_INT, /* int */ 167 NATIVE_UL, /* unsigned long */ 168 NATIVE_L, /* signed long */ 169 NATIVE_D, /* double */ 170 NATIVE_LD, /* long double */ 171 NATIVE_DC, /* double _Complex */ 172 NATIVE_LDC, /* long double _Complex */ 173 NATIVE_IM, /* intmax_t */ 174 NATIVE_UIM, /* uintmax_t */ 175 NATIVE_STRING, /* char* */ 176 GMP_Z, /* mpz_t */ 177 GMP_Q, /* mpq_t */ 178 GMP_F, /* mpf_t */ 179 MPFR_INEX, /* mpfr_inex */ 180 MPFR, /* mpfr_t */ 181 MPFR_RND, /* mpfr_rnd_t */ 182 MPC_INEX, /* mpc_inex */ 183 MPC, /* mpc_t */ 184 MPC_RND, /* mpc_rnd_t */ 185 MPCC_INEX /* mpcc_inex */ 186 } mpc_param_t; 187 188 /* additional information for checking mpfr_t result */ 189 typedef struct { 190 mpfr_t mpfr; /* skip space for the variable */ 191 int known_sign; 192 } mpfr_data_t; 193 194 #define TERNARY_NOT_CHECKED 255 195 /* special value to indicate that the ternary value is not checked */ 196 #define TERNARY_ERROR 254 197 /* special value to indicate that an error occurred in an mpc function */ 198 199 /* mpc nonary value as a pair of ternary value for data from a file */ 200 typedef struct { 201 int real; 202 int imag; 203 } mpc_inex_data_t; 204 205 /* additional information for checking mpc_t result */ 206 typedef struct { 207 mpc_t mpc; /* skip space */ 208 int known_sign_real; 209 int known_sign_imag; 210 } mpc_data_t; 211 212 /* string buffer information */ 213 typedef struct { 214 char* string; /* skip space */ 215 int length; 216 } string_info_t; 217 218 /* abstract parameter type 219 220 Let consider an abstract parameter p, which is declared as follows: 221 mpc_operand_t p; 222 we use the fact that a mpfr_t (respectively mpc_t) value can be accessed as 223 'p.mpfr' (resp. 'p.mpc') as well as 'p.mpfr_info.mpfr' 224 (resp. 'p.mpc_info.mpc'), the latter form permitting access to the 225 'known_sign' field(s). 226 Similarly, if the abstract parameter represent a string variable, we can 227 access its value with 'p.string' or 'p.string_info.string' and its size 228 with 'p.string_info.length'. 229 230 The user uses the simple form when adding a test, the second form is used by the 231 test suite itself when reading reference data and checking result against them. 232 */ 233 typedef union { 234 int i; 235 unsigned long ui; 236 signed long si; 237 double d; 238 long double ld; 239 #ifdef _MPC_H_HAVE_INTMAX_T 240 intmax_t im; 241 uintmax_t uim; 242 #endif 243 #ifdef _Complex_I 244 double _Complex dc; 245 long double _Complex ldc; 246 #endif 247 char * string; 248 string_info_t string_info; 249 mpz_t mpz; 250 mpq_t mpq; 251 mpf_t mpf; 252 mpfr_t mpfr; 253 mpfr_data_t mpfr_data; 254 mpfr_rnd_t mpfr_rnd; 255 int mpfr_inex; 256 mpc_t mpc; 257 mpc_data_t mpc_data; 258 mpc_rnd_t mpc_rnd; 259 int mpc_inex; 260 mpc_inex_data_t mpc_inex_data; 261 int mpcc_inex; 262 } mpc_operand_t; 263 264 #define PARAMETER_ARRAY_SIZE 10 265 266 /* function name plus parameters in the following order: 267 output parameters, input parameters (ending with rounding modes). 268 The input parameters include one rounding mode per mpfr/mpc 269 output starting from rnd_index. 270 For the time being, there may be either one or two rounding modes; 271 in the latter case, we assume that there are three outputs: 272 the inexact value and two complex numbers. 273 */ 274 typedef struct { 275 char *name; /* name of the function */ 276 int nbout; /* number of output parameters */ 277 int nbin; /* number of input parameters, including rounding 278 modes */ 279 int nbrnd; /* number of rounding mode parameters */ 280 mpc_operand_t P[PARAMETER_ARRAY_SIZE]; /* value of parameters */ 281 mpc_param_t T[PARAMETER_ARRAY_SIZE]; /* type of parameters */ 282 } mpc_fun_param_t; 283 284 285 void read_description (mpc_fun_param_t* param, const char *file); 286 const char* read_description_findname (mpc_param_t e); 287 288 /* file functions */ 289 typedef struct { 290 char *pathname; 291 FILE *fd; 292 unsigned long line_number; 293 unsigned long test_line_number; 294 int nextchar; 295 } mpc_datafile_context_t; 296 297 void open_datafile (mpc_datafile_context_t* datafile_context, 298 const char * data_filename); 299 void close_datafile (mpc_datafile_context_t *dc); 300 301 /* data file functions */ 302 void read_line (mpc_datafile_context_t* datafile_context, 303 mpc_fun_param_t* params); 304 void check_data (mpc_datafile_context_t* datafile_context, 305 mpc_fun_param_t* params, 306 int index_reused_operand); 307 308 /* parameters templated functions */ 309 int data_check_template (const char* descr_file, const char * data_file); 310 311 void init_parameters (mpc_fun_param_t *params); 312 void clear_parameters (mpc_fun_param_t *params); 313 void print_parameter (mpc_fun_param_t *params, int index); 314 int copy_parameter (mpc_fun_param_t *params, 315 int index_dest, int index_src); 316 317 void tpl_read_int (mpc_datafile_context_t* datafile_context, 318 int *nread, const char *name); 319 void tpl_read_ui (mpc_datafile_context_t* datafile_context, 320 unsigned long int *ui); 321 void tpl_read_si (mpc_datafile_context_t* datafile_context, 322 long int *si); 323 void tpl_read_mpz (mpc_datafile_context_t* datafile_context, 324 mpz_t z); 325 void tpl_skip_whitespace_comments (mpc_datafile_context_t* datafile_context); 326 void tpl_read_ternary (mpc_datafile_context_t* datafile_context, 327 int* ternary); 328 void tpl_read_mpfr (mpc_datafile_context_t* datafile_context, 329 mpfr_ptr x, int* known_sign); 330 void tpl_read_mpfr_rnd (mpc_datafile_context_t* datafile_context, 331 mpfr_rnd_t* rnd); 332 void tpl_read_mpfr_inex (mpc_datafile_context_t* datafile_context, 333 int *ternary); 334 void tpl_read_mpc_inex (mpc_datafile_context_t* datafile_context, 335 mpc_inex_data_t* ternarypair); 336 void tpl_read_mpc (mpc_datafile_context_t* datafile_context, 337 mpc_data_t* z); 338 void tpl_read_mpc_rnd (mpc_datafile_context_t* datafile_context, 339 mpc_rnd_t* rnd); 340 341 int tpl_same_mpz_value (mpz_ptr n1, mpz_ptr n2); 342 int tpl_same_mpfr_value (mpfr_ptr x1, mpfr_ptr x2, int known_sign); 343 int tpl_check_mpfr_data (mpfr_t got, mpfr_data_t expected); 344 int tpl_check_mpc_data (mpc_ptr got, mpc_data_t expected); 345 346 void tpl_copy_int (int *dest, const int * const src); 347 void tpl_copy_ui (unsigned long int *dest, 348 const unsigned long int * const src); 349 void tpl_copy_si (long int *dest, const long int * const src); 350 void tpl_copy_d (double *dest, const double * const src); 351 void tpl_copy_mpz (mpz_ptr dest, mpz_srcptr src); 352 void tpl_copy_mpfr (mpfr_ptr dest, mpfr_srcptr src); 353 void tpl_copy_mpc (mpc_ptr dest, mpc_srcptr src); 354 355 int double_rounding (mpc_fun_param_t *params); 356 357 /* iterating over rounding modes */ 358 void first_rnd_mode (mpc_fun_param_t *params); 359 int is_valid_rnd_mode (mpc_fun_param_t *params); 360 void next_rnd_mode (mpc_fun_param_t *params); 361 362 /* parameter precision */ 363 void set_output_precision (mpc_fun_param_t *params, mpfr_prec_t prec); 364 void set_input_precision (mpc_fun_param_t *params, mpfr_prec_t prec); 365 void set_reference_precision (mpc_fun_param_t *params, mpfr_prec_t prec); 366 367 #endif /* __MPC_TESTS_H */ 368