1/* tgeneric.c -- File for generic tests. 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#include "mpc-tests.h" 22 23/* Warning: unlike the MPFR macro (defined in mpfr-impl.h), this one returns 24 true when b is singular */ 25#define MPFR_CAN_ROUND(b,err,prec,rnd) \ 26 (mpfr_zero_p (b) || mpfr_inf_p (b) \ 27 || mpfr_can_round (b, (long)mpfr_get_prec (b) - (err), (rnd), \ 28 GMP_RNDZ, (prec) + ((rnd)==GMP_RNDN))) 29 30/* functions with one input, one output */ 31static void 32tgeneric_cc (mpc_function *function, mpc_ptr op, mpc_ptr rop, 33 mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) 34{ 35 known_signs_t ks = {1, 1}; 36 37 /* We compute the result with four times the precision and check whether the 38 rounding is correct. Error reports in this part of the algorithm might 39 still be wrong, though, since there are two consecutive roundings (but we 40 try to avoid them). */ 41 function->pointer.CC (rop4, op, rnd); 42 function->pointer.CC (rop, op, rnd); 43 44 /* can't use the mpfr_can_round function when argument is singular, 45 use a custom macro instead. */ 46 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), 47 MPC_RND_RE (rnd)) 48 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), 49 MPC_RND_IM (rnd))) 50 mpc_set (rop4rnd, rop4, rnd); 51 else 52 /* avoid double rounding error */ 53 return; 54 55 if (same_mpc_value (rop, rop4rnd, ks)) 56 return; 57 58 /* rounding failed */ 59 printf ("Rounding in %s might be incorrect for\n", function->name); 60 MPC_OUT (op); 61 62 printf ("with rounding mode (%s, %s)", 63 mpfr_print_rnd_mode (MPC_RND_RE (rnd)), 64 mpfr_print_rnd_mode (MPC_RND_IM (rnd))); 65 66 printf ("\n%s gives ", function->name); 67 MPC_OUT (rop); 68 printf ("%s quadruple precision gives ", function->name); 69 MPC_OUT (rop4); 70 printf ("and is rounded to "); 71 MPC_OUT (rop4rnd); 72 73 exit (1); 74} 75 76static void 77tgeneric_cc_c (mpc_function *function, mpc_ptr op, mpc_ptr rop1, mpc_ptr rop2, 78 mpc_ptr rop14, mpc_ptr rop24, mpc_ptr rop14rnd, mpc_ptr rop24rnd, 79 mpc_rnd_t rnd1, mpc_rnd_t rnd2) 80{ 81 /* same as the previous function, but for mpc functions computing two 82 results from one argument */ 83 known_signs_t ks = {1, 1}; 84 85 function->pointer.CC_C (rop14, rop24, op, rnd1, rnd2); 86 function->pointer.CC_C (rop1, rop2, op, rnd1, rnd2); 87 88 if ( MPFR_CAN_ROUND (mpc_realref (rop14), 1, MPC_PREC_RE (rop1), 89 MPC_RND_RE (rnd1)) 90 && MPFR_CAN_ROUND (mpc_imagref (rop14), 1, MPC_PREC_IM (rop1), 91 MPC_RND_IM (rnd1)) 92 && MPFR_CAN_ROUND (mpc_realref (rop24), 1, MPC_PREC_RE (rop2), 93 MPC_RND_RE (rnd2)) 94 && MPFR_CAN_ROUND (mpc_imagref (rop24), 1, MPC_PREC_IM (rop2), 95 MPC_RND_IM (rnd2))) { 96 mpc_set (rop14rnd, rop14, rnd1); 97 mpc_set (rop24rnd, rop24, rnd2); 98 } 99 else 100 return; 101 102 if (!same_mpc_value (rop1, rop14rnd, ks)) { 103 /* rounding failed for first result */ 104 printf ("Rounding might be incorrect for the first result of %s at\n", function->name); 105 MPC_OUT (op); 106 printf ("with rounding mode (%s, %s)", 107 mpfr_print_rnd_mode (MPC_RND_RE (rnd1)), 108 mpfr_print_rnd_mode (MPC_RND_IM (rnd1))); 109 printf ("\n%s gives ", function->name); 110 MPC_OUT (rop1); 111 printf ("%s quadruple precision gives ", function->name); 112 MPC_OUT (rop14); 113 printf ("and is rounded to "); 114 MPC_OUT (rop14rnd); 115 exit (1); 116 } 117 else if (!same_mpc_value (rop2, rop24rnd, ks)) { 118 /* rounding failed for second result */ 119 printf ("Rounding might be incorrect for the second result of %s at\n", function->name); 120 MPC_OUT (op); 121 printf ("with rounding mode (%s, %s)", 122 mpfr_print_rnd_mode (MPC_RND_RE (rnd2)), 123 mpfr_print_rnd_mode (MPC_RND_IM (rnd2))); 124 printf ("\n%s gives ", function->name); 125 MPC_OUT (rop2); 126 printf ("%s quadruple precision gives ", function->name); 127 MPC_OUT (rop24); 128 printf ("and is rounded to "); 129 MPC_OUT (rop24rnd); 130 exit (1); 131 } 132} 133 134static void 135tgeneric_fc (mpc_function *function, mpc_ptr op, mpfr_ptr rop, 136 mpfr_ptr rop4, mpfr_ptr rop4rnd, mpfr_rnd_t rnd) 137{ 138 function->pointer.FC (rop4, op, rnd); 139 function->pointer.FC (rop, op, rnd); 140 if (MPFR_CAN_ROUND (rop4, 1, mpfr_get_prec (rop), rnd)) 141 mpfr_set (rop4rnd, rop4, rnd); 142 else 143 return; 144 145 if (same_mpfr_value (rop, rop4rnd, 1)) 146 return; 147 148 printf ("Rounding in %s might be incorrect for\n", function->name); 149 MPC_OUT (op); 150 printf ("with rounding mode %s", mpfr_print_rnd_mode (rnd)); 151 152 printf ("\n%s gives ", function->name); 153 MPFR_OUT (rop); 154 printf ("%s quadruple precision gives ", function->name); 155 MPFR_OUT (rop4); 156 printf ("and is rounded to "); 157 MPFR_OUT (rop4rnd); 158 159 exit (1); 160} 161 162static void 163tgeneric_cfc (mpc_function *function, mpfr_ptr op1, mpc_ptr op2, 164 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) 165{ 166 known_signs_t ks = {1, 1}; 167 168 function->pointer.CFC (rop4, op1, op2, rnd); 169 function->pointer.CFC (rop, op1, op2, rnd); 170 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), 171 MPC_RND_RE (rnd)) 172 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), 173 MPC_RND_IM (rnd))) 174 mpc_set (rop4rnd, rop4, rnd); 175 else 176 return; 177 178 if (same_mpc_value (rop, rop4rnd, ks)) 179 return; 180 181 printf ("Rounding in %s might be incorrect for\n", function->name); 182 MPFR_OUT (op1); 183 MPC_OUT (op2); 184 printf ("with rounding mode (%s, %s)", 185 mpfr_print_rnd_mode (MPC_RND_RE (rnd)), 186 mpfr_print_rnd_mode (MPC_RND_IM (rnd))); 187 188 printf ("\n%s gives ", function->name); 189 MPC_OUT (rop); 190 printf ("%s quadruple precision gives ", function->name); 191 MPC_OUT (rop4); 192 printf ("and is rounded to "); 193 MPC_OUT (rop4rnd); 194 195 exit (1); 196} 197 198static void 199tgeneric_ccf (mpc_function *function, mpc_ptr op1, mpfr_ptr op2, 200 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) 201{ 202 known_signs_t ks = {1, 1}; 203 204 function->pointer.CCF (rop4, op1, op2, rnd); 205 function->pointer.CCF (rop, op1, op2, rnd); 206 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), 207 MPC_RND_RE (rnd)) 208 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), 209 MPC_RND_IM (rnd))) 210 mpc_set (rop4rnd, rop4, rnd); 211 else 212 return; 213 214 if (same_mpc_value (rop, rop4rnd, ks)) 215 return; 216 217 printf ("Rounding in %s might be incorrect for\n", function->name); 218 MPC_OUT (op1); 219 MPFR_OUT (op2); 220 printf ("with rounding mode (%s, %s)", 221 mpfr_print_rnd_mode (MPC_RND_RE (rnd)), 222 mpfr_print_rnd_mode (MPC_RND_IM (rnd))); 223 224 printf ("\n%s gives ", function->name); 225 MPC_OUT (rop); 226 printf ("%s quadruple precision gives ", function->name); 227 MPC_OUT (rop4); 228 printf ("and is rounded to "); 229 MPC_OUT (rop4rnd); 230 231 exit (1); 232} 233 234/* for functions with one mpc_t output, two mpc_t inputs */ 235static void 236tgeneric_c_cc (mpc_function *function, mpc_ptr op1, mpc_ptr op2, 237 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) 238{ 239 known_signs_t ks = {1, 1}; 240 241 /* We compute the result with four times the precision and check whether the 242 rounding is correct. Error reports in this part of the algorithm might 243 still be wrong, though, since there are two consecutive roundings (but we 244 try to avoid them). */ 245 function->pointer.C_CC (rop4, op1, op2, rnd); 246 function->pointer.C_CC (rop, op1, op2, rnd); 247 248 /* can't use mpfr_can_round when argument is singular */ 249 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), 250 MPC_RND_RE (rnd)) 251 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), 252 MPC_RND_IM (rnd))) 253 mpc_set (rop4rnd, rop4, rnd); 254 else 255 /* avoid double rounding error */ 256 return; 257 258 if (same_mpc_value (rop, rop4rnd, ks)) 259 return; 260 261 /* rounding failed */ 262 printf ("Rounding in %s might be incorrect for\n", function->name); 263 MPC_OUT (op1); 264 MPC_OUT (op2); 265 printf ("with rounding mode (%s, %s)", 266 mpfr_print_rnd_mode (MPC_RND_RE (rnd)), 267 mpfr_print_rnd_mode (MPC_RND_IM (rnd))); 268 269 printf ("\n%s gives ", function->name); 270 MPC_OUT (rop); 271 printf ("%s quadruple precision gives ", function->name); 272 MPC_OUT (rop4); 273 printf ("and is rounded to "); 274 MPC_OUT (rop4rnd); 275 276 exit (1); 277} 278 279static void 280tgeneric_cccc (mpc_function *function, mpc_ptr op1, mpc_ptr op2, mpc_ptr op3, 281 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) 282{ 283 known_signs_t ks = {1, 1}; 284 285 /* We compute the result with four times the precision and check whether the 286 rounding is correct. Error reports in this part of the algorithm might 287 still be wrong, though, since there are two consecutive roundings (but we 288 try to avoid them). */ 289 function->pointer.CCCC (rop4, op1, op2, op3, rnd); 290 function->pointer.CCCC (rop, op1, op2, op3, rnd); 291 292 /* can't use mpfr_can_round when argument is singular */ 293 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), 294 MPC_RND_RE (rnd)) 295 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), 296 MPC_RND_IM (rnd))) 297 mpc_set (rop4rnd, rop4, rnd); 298 else 299 /* avoid double rounding error */ 300 return; 301 302 if (same_mpc_value (rop, rop4rnd, ks)) 303 return; 304 305 /* rounding failed */ 306 printf ("Rounding in %s might be incorrect for\n", function->name); 307 MPC_OUT (op1); 308 MPC_OUT (op2); 309 MPC_OUT (op3); 310 printf ("with rounding mode (%s, %s)", 311 mpfr_print_rnd_mode (MPC_RND_RE (rnd)), 312 mpfr_print_rnd_mode (MPC_RND_IM (rnd))); 313 314 printf ("\n%s gives ", function->name); 315 MPC_OUT (rop); 316 printf ("%s quadruple precision gives ", function->name); 317 MPC_OUT (rop4); 318 printf ("and is rounded to "); 319 MPC_OUT (rop4rnd); 320 321 exit (1); 322} 323 324static void 325tgeneric_ccu (mpc_function *function, mpc_ptr op1, unsigned long int op2, 326 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) 327{ 328 known_signs_t ks = {1, 1}; 329 330 function->pointer.CCU (rop4, op1, op2, rnd); 331 function->pointer.CCU (rop, op1, op2, rnd); 332 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), 333 MPC_RND_RE (rnd)) 334 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), 335 MPC_RND_IM (rnd))) 336 mpc_set (rop4rnd, rop4, rnd); 337 else 338 return; 339 340 if (same_mpc_value (rop, rop4rnd, ks)) 341 return; 342 343 printf ("Rounding in %s might be incorrect for\n", function->name); 344 MPC_OUT (op1); 345 printf ("op2=%lu\n", op2); 346 printf ("with rounding mode (%s, %s)", 347 mpfr_print_rnd_mode (MPC_RND_RE (rnd)), 348 mpfr_print_rnd_mode (MPC_RND_IM (rnd))); 349 350 printf ("\n%s gives ", function->name); 351 MPC_OUT (rop); 352 printf ("%s quadruple precision gives ", function->name); 353 MPC_OUT (rop4); 354 printf ("and is rounded to "); 355 MPC_OUT (rop4rnd); 356 357 exit (1); 358} 359 360static void 361tgeneric_cuc (mpc_function *function, unsigned long int op1, mpc_ptr op2, 362 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) 363{ 364 known_signs_t ks = {1, 1}; 365 366 function->pointer.CUC (rop4, op1, op2, rnd); 367 function->pointer.CUC (rop, op1, op2, rnd); 368 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), 369 MPC_RND_RE (rnd)) 370 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), 371 MPC_RND_IM (rnd))) 372 mpc_set (rop4rnd, rop4, rnd); 373 else 374 return; 375 376 if (same_mpc_value (rop, rop4rnd, ks)) 377 return; 378 379 printf ("Rounding in %s might be incorrect for\n", function->name); 380 printf ("op1=%lu\n", op1); 381 MPC_OUT (op2); 382 printf ("with rounding mode (%s, %s)", 383 mpfr_print_rnd_mode (MPC_RND_RE (rnd)), 384 mpfr_print_rnd_mode (MPC_RND_IM (rnd))); 385 386 printf ("\n%s gives ", function->name); 387 MPC_OUT (rop); 388 printf ("%s quadruple precision gives ", function->name); 389 MPC_OUT (rop4); 390 printf ("and is rounded to "); 391 MPC_OUT (rop4rnd); 392 393 exit (1); 394} 395 396static void 397tgeneric_ccs (mpc_function *function, mpc_ptr op1, long int op2, 398 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) 399{ 400 known_signs_t ks = {1, 1}; 401 402 function->pointer.CCS (rop4, op1, op2, rnd); 403 function->pointer.CCS (rop, op1, op2, rnd); 404 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), 405 MPC_RND_RE (rnd)) 406 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), 407 MPC_RND_IM (rnd))) 408 mpc_set (rop4rnd, rop4, rnd); 409 else 410 return; 411 412 if (same_mpc_value (rop, rop4rnd, ks)) 413 return; 414 415 printf ("Rounding in %s might be incorrect for\n", function->name); 416 MPC_OUT (op1); 417 printf ("op2=%ld\n", op2); 418 printf ("with rounding mode (%s, %s)", 419 mpfr_print_rnd_mode (MPC_RND_RE (rnd)), 420 mpfr_print_rnd_mode (MPC_RND_IM (rnd))); 421 422 printf ("\n%s gives ", function->name); 423 MPC_OUT (rop); 424 printf ("%s quadruple precision gives ", function->name); 425 MPC_OUT (rop4); 426 printf ("and is rounded to "); 427 MPC_OUT (rop4rnd); 428 429 exit (1); 430} 431 432 433static void 434tgeneric_cci (mpc_function *function, mpc_ptr op1, int op2, 435 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) 436{ 437 known_signs_t ks = {1, 1}; 438 439 function->pointer.CCI (rop4, op1, op2, rnd); 440 function->pointer.CCI (rop, op1, op2, rnd); 441 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), 442 MPC_RND_RE (rnd)) 443 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), 444 MPC_RND_IM (rnd))) 445 mpc_set (rop4rnd, rop4, rnd); 446 else 447 return; 448 449 if (same_mpc_value (rop, rop4rnd, ks)) 450 return; 451 452 printf ("Rounding in %s might be incorrect for\n", function->name); 453 MPC_OUT (op1); 454 printf ("op2=%d\n", op2); 455 printf ("with rounding mode (%s, %s)", 456 mpfr_print_rnd_mode (MPC_RND_RE (rnd)), 457 mpfr_print_rnd_mode (MPC_RND_IM (rnd))); 458 459 printf ("\n%s gives ", function->name); 460 MPC_OUT (rop); 461 printf ("%s quadruple precision gives ", function->name); 462 MPC_OUT (rop4); 463 printf ("and is rounded to "); 464 MPC_OUT (rop4rnd); 465 466 exit (1); 467} 468 469static void 470tgeneric_cuuc (mpc_function *function, unsigned long int op1, 471 unsigned long int op2, mpc_ptr op3, mpc_ptr rop, 472 mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd) 473{ 474 known_signs_t ks = {1, 1}; 475 476 function->pointer.CUUC (rop4, op1, op2, op3, rnd); 477 function->pointer.CUUC (rop, op1, op2, op3, rnd); 478 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop), 479 MPC_RND_RE (rnd)) 480 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop), 481 MPC_RND_IM (rnd))) 482 mpc_set (rop4rnd, rop4, rnd); 483 else 484 return; 485 486 if (same_mpc_value (rop, rop4rnd, ks)) 487 return; 488 489 printf ("Rounding in %s might be incorrect for\n", function->name); 490 printf ("op1=%lu\n", op1); 491 printf ("op2=%lu\n", op2); 492 MPC_OUT (op3); 493 printf ("with rounding mode (%s, %s)", 494 mpfr_print_rnd_mode (MPC_RND_RE (rnd)), 495 mpfr_print_rnd_mode (MPC_RND_IM (rnd))); 496 497 printf ("\n%s gives ", function->name); 498 MPC_OUT (rop); 499 printf ("%s quadruple precision gives ", function->name); 500 MPC_OUT (rop4); 501 printf ("and is rounded to "); 502 MPC_OUT (rop4rnd); 503 504 exit (1); 505} 506 507 508/* Test parameter reuse: the function should not use its output parameter in 509 internal computations. */ 510static void 511reuse_cc (mpc_function* function, mpc_srcptr z, mpc_ptr got, mpc_ptr expected) 512{ 513 known_signs_t ks = {1, 1}; 514 515 mpc_set (got, z, MPC_RNDNN); /* exact */ 516 function->pointer.CC (expected, z, MPC_RNDNN); 517 function->pointer.CC (got, got, MPC_RNDNN); 518 if (!same_mpc_value (got, expected, ks)) 519 { 520 printf ("Reuse error for %s(z, z) for\n", function->name); 521 MPC_OUT (z); 522 MPC_OUT (expected); 523 MPC_OUT (got); 524 525 exit (1); 526 } 527} 528 529static void 530reuse_cc_c (mpc_function* function, mpc_srcptr z, mpc_ptr got1, mpc_ptr got2, 531 mpc_ptr exp1, mpc_ptr exp2) 532{ 533 known_signs_t ks = {1, 1}; 534 535 function->pointer.CC_C (exp1, exp2, z, MPC_RNDNN, MPC_RNDNN); 536 mpc_set (got1, z, MPC_RNDNN); /* exact */ 537 function->pointer.CC_C (got1, got2, got1, MPC_RNDNN, MPC_RNDNN); 538 if ( !same_mpc_value (got1, exp1, ks) 539 || !same_mpc_value (got2, exp2, ks)) { 540 printf ("Reuse error in first result of %s for\n", function->name); 541 MPC_OUT (z); 542 MPC_OUT (exp1); 543 MPC_OUT (got1); 544 MPC_OUT (exp2); 545 MPC_OUT (got2); 546 exit (1); 547 } 548 mpc_set (got2, z, MPC_RNDNN); /* exact */ 549 function->pointer.CC_C (got1, got2, got2, MPC_RNDNN, MPC_RNDNN); 550 if ( !same_mpc_value (got1, exp1, ks) 551 || !same_mpc_value (got2, exp2, ks)) { 552 printf ("Reuse error in second result of %s for\n", function->name); 553 MPC_OUT (z); 554 MPC_OUT (exp1); 555 MPC_OUT (got1); 556 MPC_OUT (exp2); 557 MPC_OUT (got2); 558 exit (1); 559 } 560} 561 562static void 563reuse_fc (mpc_function* function, mpc_ptr z, mpc_ptr x, mpfr_ptr expected) 564{ 565 mpc_set (x, z, MPC_RNDNN); /* exact */ 566 function->pointer.FC (expected, z, GMP_RNDN); 567 function->pointer.FC (mpc_realref (x), x, GMP_RNDN); 568 if (!same_mpfr_value (mpc_realref (x), expected, 1)) 569 { 570 mpfr_t got; 571 got[0] = mpc_realref(x)[0]; /* display sensible name */ 572 printf ("Reuse error for %s(mpc_realref(z), z) for\n", function->name); 573 MPC_OUT (z); 574 MPFR_OUT (expected); 575 MPFR_OUT (got); 576 577 exit (1); 578 } 579 mpc_set (x, z, MPC_RNDNN); /* exact */ 580 function->pointer.FC (mpc_imagref (x), x, GMP_RNDN); 581 if (!same_mpfr_value (mpc_imagref (x), expected, 1)) 582 { 583 mpfr_t got; 584 got[0] = mpc_imagref(x)[0]; /* display sensible name */ 585 printf ("Reuse error for %s(mpc_imagref(z), z) for \n", function->name); 586 MPC_OUT (z); 587 MPFR_OUT (expected); 588 MPFR_OUT (got); 589 590 exit (1); 591 } 592} 593 594static void 595reuse_cfc (mpc_function* function, mpc_srcptr z, mpfr_srcptr x, mpc_ptr got, 596 mpc_ptr expected) 597{ 598 known_signs_t ks = {1, 1}; 599 600 mpc_set (got, z, MPC_RNDNN); /* exact */ 601 function->pointer.CFC (expected, x, z, MPC_RNDNN); 602 function->pointer.CFC (got, x, got, MPC_RNDNN); 603 if (!same_mpc_value (got, expected, ks)) 604 { 605 printf ("Reuse error for %s(z, x, z) for\n", function->name); 606 MPFR_OUT (x); 607 MPC_OUT (z); 608 MPC_OUT (expected); 609 MPC_OUT (got); 610 611 exit (1); 612 } 613} 614 615static void 616reuse_ccf (mpc_function* function, mpc_srcptr z, mpfr_srcptr x, mpc_ptr got, 617 mpc_ptr expected) 618{ 619 known_signs_t ks = {1, 1}; 620 621 mpc_set (got, z, MPC_RNDNN); /* exact */ 622 function->pointer.CCF (expected, z, x, MPC_RNDNN); 623 function->pointer.CCF (got, got, x, MPC_RNDNN); 624 if (!same_mpc_value (got, expected, ks)) 625 { 626 printf ("Reuse error for %s(z, z, x, RNDNN) for\n", function->name); 627 MPC_OUT (z); 628 MPFR_OUT (x); 629 MPC_OUT (expected); 630 MPC_OUT (got); 631 632 exit (1); 633 } 634} 635 636/* for functions with one mpc_t output, two mpc_t inputs */ 637static void 638reuse_c_cc (mpc_function* function, mpc_srcptr z, mpc_srcptr x, 639 mpc_ptr got, mpc_ptr expected) 640{ 641 known_signs_t ks = {1, 1}; 642 643 mpc_set (got, z, MPC_RNDNN); /* exact */ 644 function->pointer.C_CC (expected, z, x, MPC_RNDNN); 645 function->pointer.C_CC (got, got, x, MPC_RNDNN); 646 if (!same_mpc_value (got, expected, ks)) 647 { 648 printf ("Reuse error for %s(z, z, x) for\n", function->name); 649 MPC_OUT (z); 650 MPC_OUT (x); 651 MPC_OUT (expected); 652 MPC_OUT (got); 653 654 exit (1); 655 } 656 mpc_set (got, x, MPC_RNDNN); /* exact */ 657 function->pointer.C_CC (expected, z, x, MPC_RNDNN); 658 function->pointer.C_CC (got, z, got, MPC_RNDNN); 659 if (!same_mpc_value (got, expected, ks)) 660 { 661 printf ("Reuse error for %s(x, z, x) for\n", function->name); 662 MPC_OUT (z); 663 MPC_OUT (x); 664 MPC_OUT (expected); 665 MPC_OUT (got); 666 667 exit (1); 668 } 669 mpc_set (got, x, MPC_RNDNN); /* exact */ 670 function->pointer.C_CC (expected, x, x, MPC_RNDNN); 671 function->pointer.C_CC (got, got, got, MPC_RNDNN); 672 if (!same_mpc_value (got, expected, ks)) 673 { 674 printf ("Reuse error for %s(x, x, x) for\n", function->name); 675 MPC_OUT (x); 676 MPC_OUT (expected); 677 MPC_OUT (got); 678 679 exit (1); 680 } 681} 682 683static void 684reuse_cccc (mpc_function* function, mpc_srcptr z, mpc_srcptr x, mpc_srcptr y, 685 mpc_ptr got, mpc_ptr expected) 686{ 687 known_signs_t ks = {1, 1}; 688 689 mpc_set (got, z, MPC_RNDNN); /* exact */ 690 function->pointer.CCCC (expected, z, x, y, MPC_RNDNN); 691 function->pointer.CCCC (got, got, x, y, MPC_RNDNN); 692 if (!same_mpc_value (got, expected, ks)) 693 { 694 printf ("Reuse error for %s(z, z, x, y) for\n", function->name); 695 MPC_OUT (z); 696 MPC_OUT (x); 697 MPC_OUT (y); 698 MPC_OUT (expected); 699 MPC_OUT (got); 700 701 exit (1); 702 } 703 704 mpc_set (got, x, MPC_RNDNN); /* exact */ 705 function->pointer.CCCC (expected, z, x, y, MPC_RNDNN); 706 function->pointer.CCCC (got, z, got, y, MPC_RNDNN); 707 if (!same_mpc_value (got, expected, ks)) 708 { 709 printf ("Reuse error for %s(x, z, x, y) for\n", function->name); 710 MPC_OUT (z); 711 MPC_OUT (x); 712 MPC_OUT (y); 713 MPC_OUT (expected); 714 MPC_OUT (got); 715 716 exit (1); 717 } 718 719 mpc_set (got, y, MPC_RNDNN); /* exact */ 720 function->pointer.CCCC (expected, z, x, y, MPC_RNDNN); 721 function->pointer.CCCC (got, z, x, got, MPC_RNDNN); 722 if (!same_mpc_value (got, expected, ks)) 723 { 724 printf ("Reuse error for %s(y, z, x, y) for\n", function->name); 725 MPC_OUT (z); 726 MPC_OUT (x); 727 MPC_OUT (y); 728 MPC_OUT (expected); 729 MPC_OUT (got); 730 731 exit (1); 732 } 733 734 mpc_set (got, x, MPC_RNDNN); /* exact */ 735 function->pointer.CCCC (expected, x, x, x, MPC_RNDNN); 736 function->pointer.CCCC (got, got, got, got, MPC_RNDNN); 737 if (!same_mpc_value (got, expected, ks)) 738 { 739 printf ("Reuse error for %s(x, x, x, x) for\n", function->name); 740 MPC_OUT (x); 741 MPC_OUT (expected); 742 MPC_OUT (got); 743 744 exit (1); 745 } 746} 747 748static void 749reuse_ccu (mpc_function* function, mpc_srcptr z, unsigned long ul, 750 mpc_ptr got, mpc_ptr expected) 751{ 752 known_signs_t ks = {1, 1}; 753 754 mpc_set (got, z, MPC_RNDNN); /* exact */ 755 function->pointer.CCU (expected, z, ul, MPC_RNDNN); 756 function->pointer.CCU (got, got, ul, MPC_RNDNN); 757 if (!same_mpc_value (got, expected, ks)) 758 { 759 printf ("Reuse error for %s(z, z, n) for\n", function->name); 760 MPC_OUT (z); 761 printf ("n=%lu\n", ul); 762 MPC_OUT (expected); 763 MPC_OUT (got); 764 765 exit (1); 766 } 767} 768 769static void 770reuse_cuc (mpc_function* function, unsigned long ul, mpc_srcptr z, 771 mpc_ptr got, mpc_ptr expected) 772{ 773 known_signs_t ks = {1, 1}; 774 775 mpc_set (got, z, MPC_RNDNN); /* exact */ 776 function->pointer.CUC (expected, ul, z,MPC_RNDNN); 777 function->pointer.CUC (got, ul, got, MPC_RNDNN); 778 if (!same_mpc_value (got, expected, ks)) 779 { 780 printf ("Reuse error for %s(z, n, z) for\n", function->name); 781 printf ("n=%lu\n", ul); 782 MPC_OUT (z); 783 MPC_OUT (expected); 784 MPC_OUT (got); 785 786 exit (1); 787 } 788} 789 790static void 791reuse_ccs (mpc_function* function, mpc_srcptr z, long lo, 792 mpc_ptr got, mpc_ptr expected) 793{ 794 known_signs_t ks = {1, 1}; 795 796 mpc_set (got, z, MPC_RNDNN); /* exact */ 797 function->pointer.CCS (expected, z, lo, MPC_RNDNN); 798 function->pointer.CCS (got, got, lo, MPC_RNDNN); 799 if (!same_mpc_value (got, expected, ks)) 800 { 801 printf ("Reuse error for %s(z, z, n) for\n", function->name); 802 MPC_OUT (z); 803 printf ("n=%ld\n", lo); 804 MPC_OUT (expected); 805 MPC_OUT (got); 806 807 exit (1); 808 } 809} 810 811static void 812reuse_cci (mpc_function* function, mpc_srcptr z, int i, 813 mpc_ptr got, mpc_ptr expected) 814{ 815 known_signs_t ks = {1, 1}; 816 817 mpc_set (got, z, MPC_RNDNN); /* exact */ 818 function->pointer.CCI (expected, z, i, MPC_RNDNN); 819 function->pointer.CCI (got, got, i, MPC_RNDNN); 820 if (!same_mpc_value (got, expected, ks)) 821 { 822 printf ("Reuse error for %s(z, z, n) for\n", function->name); 823 MPC_OUT (z); 824 printf ("n=%d\n", i); 825 MPC_OUT (expected); 826 MPC_OUT (got); 827 828 exit (1); 829 } 830} 831 832static void 833reuse_cuuc (mpc_function* function, unsigned long ul1, unsigned long ul2, 834 mpc_srcptr z, mpc_ptr got, mpc_ptr expected) 835{ 836 known_signs_t ks = {1, 1}; 837 838 mpc_set (got, z, MPC_RNDNN); /* exact */ 839 function->pointer.CUUC (expected, ul1, ul2, z,MPC_RNDNN); 840 function->pointer.CUUC (got, ul1, ul2, got, MPC_RNDNN); 841 if (!same_mpc_value (got, expected, ks)) 842 { 843 printf ("Reuse error for %s(z, m, n, z) for\n", function->name); 844 printf ("m=%lu\n", ul1); 845 printf ("n=%lu\n", ul2); 846 MPC_OUT (z); 847 MPC_OUT (expected); 848 MPC_OUT (got); 849 850 exit (1); 851 } 852} 853 854 855/* helper functions for iterating over mpfr rounding modes */ 856static mpfr_rnd_t 857first_rnd_mode (void) 858{ 859 return GMP_RNDN; 860} 861 862static mpfr_rnd_t 863next_rnd_mode (mpfr_rnd_t curr) 864 /* assumes that all rounding modes are non-negative, and returns -1 865 when curr is the last rounding mode */ 866{ 867 switch (curr) { 868 case GMP_RNDN: 869 return GMP_RNDZ; 870 case GMP_RNDZ: 871 return GMP_RNDU; 872 case GMP_RNDU: 873 return GMP_RNDD; 874 default: 875 /* return invalid guard value in mpfr_rnd_t */ 876#if MPFR_VERSION_MAJOR < 3 877 return GMP_RNDNA; 878#else 879 return MPFR_RNDA; /* valid rounding type, but not (yet) used in mpc */ 880#endif 881 } 882} 883 884static int 885is_valid_rnd_mode (mpfr_rnd_t curr) 886 /* returns 1 if curr is a valid rounding mode, and 0otherwise */ 887{ 888 if ( curr == GMP_RNDN || curr == GMP_RNDZ 889 || curr == GMP_RNDU || curr == GMP_RNDD) 890 return 1; 891 else 892 return 0; 893} 894 895/* tgeneric(prec_min, prec_max, step, exp_max) checks rounding with random 896 numbers: 897 - with precision ranging from prec_min to prec_max with an increment of 898 step, 899 - with exponent between -exp_max and exp_max. 900 901 It also checks parameter reuse (it is assumed here that either two mpc_t 902 variables are equal or they are different, in the sense that the real part 903 of one of them cannot be the imaginary part of the other). */ 904void 905tgeneric (mpc_function function, mpfr_prec_t prec_min, 906 mpfr_prec_t prec_max, mpfr_prec_t step, mpfr_exp_t exp_max) 907{ 908 unsigned long ul1 = 0, ul2 = 0; 909 long lo = 0; 910 int i = 0; 911 mpfr_t x1, x2, xxxx; 912 mpc_t z1, z2, z3, z4, z5, zzzz, zzzz2; 913 914 mpfr_rnd_t rnd_re, rnd_im, rnd2_re, rnd2_im; 915 mpfr_prec_t prec; 916 mpfr_exp_t exp_min; 917 int special, special_cases; 918 919 mpc_init2 (z1, prec_max); 920 switch (function.type) 921 { 922 case C_CC: 923 mpc_init2 (z2, prec_max); 924 mpc_init2 (z3, prec_max); 925 mpc_init2 (z4, prec_max); 926 mpc_init2 (zzzz, 4*prec_max); 927 special_cases = 8; 928 break; 929 case CCCC: 930 mpc_init2 (z2, prec_max); 931 mpc_init2 (z3, prec_max); 932 mpc_init2 (z4, prec_max); 933 mpc_init2 (z5, prec_max); 934 mpc_init2 (zzzz, 4*prec_max); 935 special_cases = 8; 936 break; 937 case FC: 938 mpfr_init2 (x1, prec_max); 939 mpfr_init2 (x2, prec_max); 940 mpfr_init2 (xxxx, 4*prec_max); 941 mpc_init2 (z2, prec_max); 942 special_cases = 4; 943 break; 944 case CCF: case CFC: 945 mpfr_init2 (x1, prec_max); 946 mpc_init2 (z2, prec_max); 947 mpc_init2 (z3, prec_max); 948 mpc_init2 (zzzz, 4*prec_max); 949 special_cases = 6; 950 break; 951 case CCI: case CCS: 952 case CCU: case CUC: 953 mpc_init2 (z2, prec_max); 954 mpc_init2 (z3, prec_max); 955 mpc_init2 (zzzz, 4*prec_max); 956 special_cases = 5; 957 break; 958 case CUUC: 959 mpc_init2 (z2, prec_max); 960 mpc_init2 (z3, prec_max); 961 mpc_init2 (zzzz, 4*prec_max); 962 special_cases = 6; 963 break; 964 case CC_C: 965 mpc_init2 (z2, prec_max); 966 mpc_init2 (z3, prec_max); 967 mpc_init2 (z4, prec_max); 968 mpc_init2 (z5, prec_max); 969 mpc_init2 (zzzz, 4*prec_max); 970 mpc_init2 (zzzz2, 4*prec_max); 971 special_cases = 4; 972 break; 973 case CC: 974 default: 975 mpc_init2 (z2, prec_max); 976 mpc_init2 (z3, prec_max); 977 mpc_init2 (zzzz, 4*prec_max); 978 special_cases = 4; 979 } 980 981 exp_min = mpfr_get_emin (); 982 if (exp_max <= 0 || exp_max > mpfr_get_emax ()) 983 exp_max = mpfr_get_emax(); 984 if (-exp_max > exp_min) 985 exp_min = - exp_max; 986 987 if (step < 1) 988 step = 1; 989 990 for (prec = prec_min, special = 0; 991 prec <= prec_max || special <= special_cases; 992 prec+=step, special += (prec > prec_max ? 1 : 0)) { 993 /* In the end, test functions in special cases of purely real, purely 994 imaginary or infinite arguments. */ 995 996 /* probability of one zero part in 256th (25 is almost 10%) */ 997 const unsigned int zero_probability = special != 0 ? 0 : 25; 998 999 mpc_set_prec (z1, prec); 1000 test_default_random (z1, exp_min, exp_max, 128, zero_probability); 1001 1002 switch (function.type) 1003 { 1004 case C_CC: 1005 mpc_set_prec (z2, prec); 1006 test_default_random (z2, exp_min, exp_max, 128, zero_probability); 1007 mpc_set_prec (z3, prec); 1008 mpc_set_prec (z4, prec); 1009 mpc_set_prec (zzzz, 4*prec); 1010 switch (special) 1011 { 1012 case 1: 1013 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); 1014 break; 1015 case 2: 1016 mpfr_set_inf (mpc_realref (z1), +1); 1017 break; 1018 case 3: 1019 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); 1020 break; 1021 case 4: 1022 mpfr_set_inf (mpc_imagref (z1), -1); 1023 break; 1024 case 5: 1025 mpfr_set_ui (mpc_realref (z2), 0, GMP_RNDN); 1026 break; 1027 case 6: 1028 mpfr_set_inf (mpc_realref (z2), -1); 1029 break; 1030 case 7: 1031 mpfr_set_ui (mpc_imagref (z2), 0, GMP_RNDN); 1032 break; 1033 case 8: 1034 mpfr_set_inf (mpc_imagref (z2), +1); 1035 break; 1036 } 1037 break; 1038 case CCCC: 1039 mpc_set_prec (z2, prec); 1040 test_default_random (z2, exp_min, exp_max, 128, zero_probability); 1041 mpc_set_prec (z3, prec); 1042 mpc_set_prec (z4, prec); 1043 mpc_set_prec (z5, prec); 1044 mpc_set_prec (zzzz, 4*prec); 1045 switch (special) 1046 { 1047 case 1: 1048 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); 1049 break; 1050 case 2: 1051 mpfr_set_inf (mpc_realref (z1), +1); 1052 break; 1053 case 3: 1054 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); 1055 break; 1056 case 4: 1057 mpfr_set_inf (mpc_imagref (z1), -1); 1058 break; 1059 case 5: 1060 mpfr_set_ui (mpc_realref (z2), 0, GMP_RNDN); 1061 break; 1062 case 6: 1063 mpfr_set_inf (mpc_realref (z2), -1); 1064 break; 1065 case 7: 1066 mpfr_set_ui (mpc_imagref (z2), 0, GMP_RNDN); 1067 break; 1068 case 8: 1069 mpfr_set_inf (mpc_imagref (z2), +1); 1070 break; 1071 } 1072 break; 1073 case FC: 1074 mpc_set_prec (z2, prec); 1075 mpfr_set_prec (x1, prec); 1076 mpfr_set_prec (x2, prec); 1077 mpfr_set_prec (xxxx, 4*prec); 1078 switch (special) 1079 { 1080 case 1: 1081 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); 1082 break; 1083 case 2: 1084 mpfr_set_inf (mpc_realref (z1), +1); 1085 break; 1086 case 3: 1087 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); 1088 break; 1089 case 4: 1090 mpfr_set_inf (mpc_imagref (z1), -1); 1091 break; 1092 } 1093 break; 1094 case CCU: case CUC: 1095 mpc_set_prec (z2, 128); 1096 do { 1097 test_default_random (z2, 0, 64, 128, zero_probability); 1098 } while (!mpfr_fits_ulong_p (mpc_realref (z2), GMP_RNDN)); 1099 ul1 = mpfr_get_ui (mpc_realref(z2), GMP_RNDN); 1100 mpc_set_prec (z2, prec); 1101 mpc_set_prec (z3, prec); 1102 mpc_set_prec (zzzz, 4*prec); 1103 switch (special) 1104 { 1105 case 1: 1106 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); 1107 break; 1108 case 2: 1109 mpfr_set_inf (mpc_realref (z1), +1); 1110 break; 1111 case 3: 1112 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); 1113 break; 1114 case 4: 1115 mpfr_set_inf (mpc_imagref (z1), -1); 1116 break; 1117 case 5: 1118 ul1 = 0; 1119 break; 1120 } 1121 break; 1122 case CUUC: 1123 mpc_set_prec (z2, 128); 1124 do { 1125 test_default_random (z2, 0, 64, 128, zero_probability); 1126 } while (!mpfr_fits_ulong_p (mpc_realref (z2), GMP_RNDN) 1127 ||!mpfr_fits_ulong_p (mpc_imagref (z2), GMP_RNDN)); 1128 ul1 = mpfr_get_ui (mpc_realref(z2), GMP_RNDN); 1129 ul2 = mpfr_get_ui (mpc_imagref(z2), GMP_RNDN); 1130 mpc_set_prec (z2, prec); 1131 mpc_set_prec (z3, prec); 1132 mpc_set_prec (zzzz, 4*prec); 1133 switch (special) 1134 { 1135 case 1: 1136 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); 1137 break; 1138 case 2: 1139 mpfr_set_inf (mpc_realref (z1), +1); 1140 break; 1141 case 3: 1142 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); 1143 break; 1144 case 4: 1145 mpfr_set_inf (mpc_imagref (z1), -1); 1146 break; 1147 case 5: 1148 ul1 = 0; 1149 break; 1150 case 6: 1151 ul2 = 0; 1152 break; 1153 } 1154 break; 1155 case CCS: 1156 mpc_set_prec (z2, 128); 1157 do { 1158 test_default_random (z2, 0, 64, 128, zero_probability); 1159 } while (!mpfr_fits_slong_p (mpc_realref (z2), GMP_RNDN)); 1160 lo = mpfr_get_si (mpc_realref(z2), GMP_RNDN); 1161 mpc_set_prec (z2, prec); 1162 mpc_set_prec (z3, prec); 1163 mpc_set_prec (zzzz, 4*prec); 1164 switch (special) 1165 { 1166 case 1: 1167 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); 1168 break; 1169 case 2: 1170 mpfr_set_inf (mpc_realref (z1), +1); 1171 break; 1172 case 3: 1173 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); 1174 break; 1175 case 4: 1176 mpfr_set_inf (mpc_imagref (z1), -1); 1177 break; 1178 case 5: 1179 lo = 0; 1180 break; 1181 } 1182 break; 1183 case CCI: 1184 mpc_set_prec (z2, 128); 1185 do { 1186 test_default_random (z2, 0, 64, 128, zero_probability); 1187 } while (!mpfr_fits_slong_p (mpc_realref (z2), GMP_RNDN)); 1188 i = (int)mpfr_get_si (mpc_realref(z2), GMP_RNDN); 1189 mpc_set_prec (z2, prec); 1190 mpc_set_prec (z3, prec); 1191 mpc_set_prec (zzzz, 4*prec); 1192 switch (special) 1193 { 1194 case 1: 1195 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); 1196 break; 1197 case 2: 1198 mpfr_set_inf (mpc_realref (z1), +1); 1199 break; 1200 case 3: 1201 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); 1202 break; 1203 case 4: 1204 mpfr_set_inf (mpc_imagref (z1), -1); 1205 break; 1206 case 5: 1207 i = 0; 1208 break; 1209 } 1210 break; 1211 case CCF: case CFC: 1212 mpfr_set_prec (x1, prec); 1213 mpfr_set (x1, mpc_realref (z1), GMP_RNDN); 1214 test_default_random (z1, exp_min, exp_max, 128, zero_probability); 1215 mpc_set_prec (z2, prec); 1216 mpc_set_prec (z3, prec); 1217 mpc_set_prec (zzzz, 4*prec); 1218 switch (special) 1219 { 1220 case 1: 1221 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); 1222 break; 1223 case 2: 1224 mpfr_set_inf (mpc_realref (z1), +1); 1225 break; 1226 case 3: 1227 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); 1228 break; 1229 case 4: 1230 mpfr_set_inf (mpc_imagref (z1), -1); 1231 break; 1232 case 5: 1233 mpfr_set_ui (x1, 0, GMP_RNDN); 1234 break; 1235 case 6: 1236 mpfr_set_inf (x1, +1); 1237 break; 1238 } 1239 break; 1240 case CC_C: 1241 mpc_set_prec (z2, prec); 1242 mpc_set_prec (z3, prec); 1243 mpc_set_prec (z4, prec); 1244 mpc_set_prec (z5, prec); 1245 mpc_set_prec (zzzz, 4*prec); 1246 mpc_set_prec (zzzz2, 4*prec); 1247 switch (special) 1248 { 1249 case 1: 1250 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); 1251 break; 1252 case 2: 1253 mpfr_set_inf (mpc_realref (z1), +1); 1254 break; 1255 case 3: 1256 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); 1257 break; 1258 case 4: 1259 mpfr_set_inf (mpc_imagref (z1), -1); 1260 break; 1261 } 1262 break; 1263 case CC: 1264 default: 1265 mpc_set_prec (z2, prec); 1266 mpc_set_prec (z3, prec); 1267 mpc_set_prec (zzzz, 4*prec); 1268 switch (special) 1269 { 1270 case 1: 1271 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN); 1272 break; 1273 case 2: 1274 mpfr_set_inf (mpc_realref (z1), +1); 1275 break; 1276 case 3: 1277 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN); 1278 break; 1279 case 4: 1280 mpfr_set_inf (mpc_imagref (z1), -1); 1281 break; 1282 } 1283 } 1284 1285 for (rnd_re = first_rnd_mode (); is_valid_rnd_mode (rnd_re); rnd_re = next_rnd_mode (rnd_re)) 1286 switch (function.type) 1287 { 1288 case C_CC: 1289 for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) 1290 tgeneric_c_cc (&function, z1, z2, z3, zzzz, z4, 1291 MPC_RND (rnd_re, rnd_im)); 1292 reuse_c_cc (&function, z1, z2, z3, z4); 1293 break; 1294 case CCCC: 1295 for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) 1296 tgeneric_cccc (&function, z1, z2, z3, z4, zzzz, z5, 1297 MPC_RND (rnd_re, rnd_im)); 1298 reuse_cccc (&function, z1, z2, z3, z4, z5); 1299 break; 1300 case FC: 1301 tgeneric_fc (&function, z1, x1, xxxx, x2, rnd_re); 1302 reuse_fc (&function, z1, z2, x1); 1303 break; 1304 case CC: 1305 for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) 1306 tgeneric_cc (&function, z1, z2, zzzz, z3, 1307 MPC_RND (rnd_re, rnd_im)); 1308 reuse_cc (&function, z1, z2, z3); 1309 break; 1310 case CC_C: 1311 for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) 1312 for (rnd2_re = first_rnd_mode (); is_valid_rnd_mode (rnd2_re); rnd2_re = next_rnd_mode (rnd2_re)) 1313 for (rnd2_im = first_rnd_mode (); is_valid_rnd_mode (rnd2_im); rnd2_im = next_rnd_mode (rnd2_im)) 1314 tgeneric_cc_c (&function, z1, z2, z3, zzzz, zzzz2, z4, z5, 1315 MPC_RND (rnd_re, rnd_im), MPC_RND (rnd2_re, rnd2_im)); 1316 reuse_cc_c (&function, z1, z2, z3, z4, z5); 1317 break; 1318 case CFC: 1319 for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) 1320 tgeneric_cfc (&function, x1, z1, z2, zzzz, z3, 1321 MPC_RND (rnd_re, rnd_im)); 1322 reuse_cfc (&function, z1, x1, z2, z3); 1323 break; 1324 case CCF: 1325 for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) 1326 tgeneric_ccf (&function, z1, x1, z2, zzzz, z3, 1327 MPC_RND (rnd_re, rnd_im)); 1328 reuse_ccf (&function, z1, x1, z2, z3); 1329 break; 1330 case CCU: 1331 for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) 1332 tgeneric_ccu (&function, z1, ul1, z2, zzzz, z3, 1333 MPC_RND (rnd_re, rnd_im)); 1334 reuse_ccu (&function, z1, ul1, z2, z3); 1335 break; 1336 case CUC: 1337 for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) 1338 tgeneric_cuc (&function, ul1, z1, z2, zzzz, z3, 1339 MPC_RND (rnd_re, rnd_im)); 1340 reuse_cuc (&function, ul1, z1, z2, z3); 1341 break; 1342 case CCS: 1343 for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) 1344 tgeneric_ccs (&function, z1, lo, z2, zzzz, z3, 1345 MPC_RND (rnd_re, rnd_im)); 1346 reuse_ccs (&function, z1, lo, z2, z3); 1347 break; 1348 case CCI: 1349 for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) 1350 tgeneric_cci (&function, z1, i, z2, zzzz, z3, 1351 MPC_RND (rnd_re, rnd_im)); 1352 reuse_cci (&function, z1, i, z2, z3); 1353 break; 1354 case CUUC: 1355 for (rnd_im = first_rnd_mode (); is_valid_rnd_mode (rnd_im); rnd_im = next_rnd_mode (rnd_im)) 1356 tgeneric_cuuc (&function, ul1, ul2, z1, z2, zzzz, z3, 1357 MPC_RND (rnd_re, rnd_im)); 1358 reuse_cuuc (&function, ul1, ul2, z1, z2, z3); 1359 break; 1360 default: 1361 printf ("tgeneric not yet implemented for this kind of" 1362 "function\n"); 1363 exit (1); 1364 } 1365 } 1366 1367 mpc_clear (z1); 1368 switch (function.type) 1369 { 1370 case C_CC: 1371 mpc_clear (z2); 1372 mpc_clear (z3); 1373 mpc_clear (z4); 1374 mpc_clear (zzzz); 1375 break; 1376 case CCCC: 1377 mpc_clear (z2); 1378 mpc_clear (z3); 1379 mpc_clear (z4); 1380 mpc_clear (z5); 1381 mpc_clear (zzzz); 1382 break; 1383 case FC: 1384 mpc_clear (z2); 1385 mpfr_clear (x1); 1386 mpfr_clear (x2); 1387 mpfr_clear (xxxx); 1388 break; 1389 case CCF: case CFC: 1390 mpfr_clear (x1); 1391 mpc_clear (z2); 1392 mpc_clear (z3); 1393 mpc_clear (zzzz); 1394 break; 1395 case CC_C: 1396 mpc_clear (z2); 1397 mpc_clear (z3); 1398 mpc_clear (z4); 1399 mpc_clear (z5); 1400 mpc_clear (zzzz); 1401 mpc_clear (zzzz2); 1402 break; 1403 case CUUC: 1404 case CCI: case CCS: 1405 case CCU: case CUC: 1406 case CC: 1407 default: 1408 mpc_clear (z2); 1409 mpc_clear (z3); 1410 mpc_clear (zzzz); 1411 } 1412} 1413