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