1 /* tgeneric.c -- File for generic tests.
3 Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA
5 This file is part of GNU MPC.
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.
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
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/ .
21 #include "mpc-tests.h"
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)))
30 /* functions with one input, one output */
32 tgeneric_cc (mpc_function *function, mpc_ptr op, mpc_ptr rop,
33 mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
35 known_signs_t ks = {1, 1};
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);
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),
48 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
50 mpc_set (rop4rnd, rop4, rnd);
52 /* avoid double rounding error */
55 if (same_mpc_value (rop, rop4rnd, ks))
59 printf ("Rounding in %s might be incorrect for\n", function->name);
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)));
66 printf ("\n%s gives ", function->name);
68 printf ("%s quadruple precision gives ", function->name);
70 printf ("and is rounded to ");
77 tgeneric_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)
81 /* same as the previous function, but for mpc functions computing two
82 results from one argument */
83 known_signs_t ks = {1, 1};
85 function->pointer.CC_C (rop14, rop24, op, rnd1, rnd2);
86 function->pointer.CC_C (rop1, rop2, op, rnd1, rnd2);
88 if ( MPFR_CAN_ROUND (mpc_realref (rop14), 1, MPC_PREC_RE (rop1),
90 && MPFR_CAN_ROUND (mpc_imagref (rop14), 1, MPC_PREC_IM (rop1),
92 && MPFR_CAN_ROUND (mpc_realref (rop24), 1, MPC_PREC_RE (rop2),
94 && MPFR_CAN_ROUND (mpc_imagref (rop24), 1, MPC_PREC_IM (rop2),
96 mpc_set (rop14rnd, rop14, rnd1);
97 mpc_set (rop24rnd, rop24, rnd2);
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);
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);
111 printf ("%s quadruple precision gives ", function->name);
113 printf ("and is rounded to ");
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);
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);
126 printf ("%s quadruple precision gives ", function->name);
128 printf ("and is rounded to ");
135 tgeneric_fc (mpc_function *function, mpc_ptr op, mpfr_ptr rop,
136 mpfr_ptr rop4, mpfr_ptr rop4rnd, mpfr_rnd_t rnd)
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);
145 if (same_mpfr_value (rop, rop4rnd, 1))
148 printf ("Rounding in %s might be incorrect for\n", function->name);
150 printf ("with rounding mode %s", mpfr_print_rnd_mode (rnd));
152 printf ("\n%s gives ", function->name);
154 printf ("%s quadruple precision gives ", function->name);
156 printf ("and is rounded to ");
163 tgeneric_cfc (mpc_function *function, mpfr_ptr op1, mpc_ptr op2,
164 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
166 known_signs_t ks = {1, 1};
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),
172 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
174 mpc_set (rop4rnd, rop4, rnd);
178 if (same_mpc_value (rop, rop4rnd, ks))
181 printf ("Rounding in %s might be incorrect for\n", function->name);
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)));
188 printf ("\n%s gives ", function->name);
190 printf ("%s quadruple precision gives ", function->name);
192 printf ("and is rounded to ");
199 tgeneric_ccf (mpc_function *function, mpc_ptr op1, mpfr_ptr op2,
200 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
202 known_signs_t ks = {1, 1};
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),
208 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
210 mpc_set (rop4rnd, rop4, rnd);
214 if (same_mpc_value (rop, rop4rnd, ks))
217 printf ("Rounding in %s might be incorrect for\n", function->name);
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)));
224 printf ("\n%s gives ", function->name);
226 printf ("%s quadruple precision gives ", function->name);
228 printf ("and is rounded to ");
234 /* for functions with one mpc_t output, two mpc_t inputs */
236 tgeneric_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)
239 known_signs_t ks = {1, 1};
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);
248 /* can't use mpfr_can_round when argument is singular */
249 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
251 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
253 mpc_set (rop4rnd, rop4, rnd);
255 /* avoid double rounding error */
258 if (same_mpc_value (rop, rop4rnd, ks))
261 /* rounding failed */
262 printf ("Rounding in %s might be incorrect for\n", function->name);
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)));
269 printf ("\n%s gives ", function->name);
271 printf ("%s quadruple precision gives ", function->name);
273 printf ("and is rounded to ");
280 tgeneric_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)
283 known_signs_t ks = {1, 1};
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);
292 /* can't use mpfr_can_round when argument is singular */
293 if (MPFR_CAN_ROUND (mpc_realref (rop4), 1, MPC_PREC_RE (rop),
295 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
297 mpc_set (rop4rnd, rop4, rnd);
299 /* avoid double rounding error */
302 if (same_mpc_value (rop, rop4rnd, ks))
305 /* rounding failed */
306 printf ("Rounding in %s might be incorrect for\n", function->name);
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)));
314 printf ("\n%s gives ", function->name);
316 printf ("%s quadruple precision gives ", function->name);
318 printf ("and is rounded to ");
325 tgeneric_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)
328 known_signs_t ks = {1, 1};
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),
334 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
336 mpc_set (rop4rnd, rop4, rnd);
340 if (same_mpc_value (rop, rop4rnd, ks))
343 printf ("Rounding in %s might be incorrect for\n", function->name);
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)));
350 printf ("\n%s gives ", function->name);
352 printf ("%s quadruple precision gives ", function->name);
354 printf ("and is rounded to ");
361 tgeneric_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)
364 known_signs_t ks = {1, 1};
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),
370 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
372 mpc_set (rop4rnd, rop4, rnd);
376 if (same_mpc_value (rop, rop4rnd, ks))
379 printf ("Rounding in %s might be incorrect for\n", function->name);
380 printf ("op1=%lu\n", op1);
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)));
386 printf ("\n%s gives ", function->name);
388 printf ("%s quadruple precision gives ", function->name);
390 printf ("and is rounded to ");
397 tgeneric_ccs (mpc_function *function, mpc_ptr op1, long int op2,
398 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
400 known_signs_t ks = {1, 1};
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),
406 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
408 mpc_set (rop4rnd, rop4, rnd);
412 if (same_mpc_value (rop, rop4rnd, ks))
415 printf ("Rounding in %s might be incorrect for\n", function->name);
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)));
422 printf ("\n%s gives ", function->name);
424 printf ("%s quadruple precision gives ", function->name);
426 printf ("and is rounded to ");
434 tgeneric_cci (mpc_function *function, mpc_ptr op1, int op2,
435 mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
437 known_signs_t ks = {1, 1};
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),
443 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
445 mpc_set (rop4rnd, rop4, rnd);
449 if (same_mpc_value (rop, rop4rnd, ks))
452 printf ("Rounding in %s might be incorrect for\n", function->name);
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)));
459 printf ("\n%s gives ", function->name);
461 printf ("%s quadruple precision gives ", function->name);
463 printf ("and is rounded to ");
470 tgeneric_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)
474 known_signs_t ks = {1, 1};
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),
480 && MPFR_CAN_ROUND (mpc_imagref (rop4), 1, MPC_PREC_IM (rop),
482 mpc_set (rop4rnd, rop4, rnd);
486 if (same_mpc_value (rop, rop4rnd, ks))
489 printf ("Rounding in %s might be incorrect for\n", function->name);
490 printf ("op1=%lu\n", op1);
491 printf ("op2=%lu\n", op2);
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)));
497 printf ("\n%s gives ", function->name);
499 printf ("%s quadruple precision gives ", function->name);
501 printf ("and is rounded to ");
508 /* Test parameter reuse: the function should not use its output parameter in
509 internal computations. */
511 reuse_cc (mpc_function* function, mpc_srcptr z, mpc_ptr got, mpc_ptr expected)
513 known_signs_t ks = {1, 1};
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))
520 printf ("Reuse error for %s(z, z) for\n", function->name);
530 reuse_cc_c (mpc_function* function, mpc_srcptr z, mpc_ptr got1, mpc_ptr got2,
531 mpc_ptr exp1, mpc_ptr exp2)
533 known_signs_t ks = {1, 1};
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);
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);
563 reuse_fc (mpc_function* function, mpc_ptr z, mpc_ptr x, mpfr_ptr expected)
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))
571 got[0] = mpc_realref(x)[0]; /* display sensible name */
572 printf ("Reuse error for %s(mpc_realref(z), z) for\n", function->name);
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))
584 got[0] = mpc_imagref(x)[0]; /* display sensible name */
585 printf ("Reuse error for %s(mpc_imagref(z), z) for \n", function->name);
595 reuse_cfc (mpc_function* function, mpc_srcptr z, mpfr_srcptr x, mpc_ptr got,
598 known_signs_t ks = {1, 1};
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))
605 printf ("Reuse error for %s(z, x, z) for\n", function->name);
616 reuse_ccf (mpc_function* function, mpc_srcptr z, mpfr_srcptr x, mpc_ptr got,
619 known_signs_t ks = {1, 1};
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))
626 printf ("Reuse error for %s(z, z, x, RNDNN) for\n", function->name);
636 /* for functions with one mpc_t output, two mpc_t inputs */
638 reuse_c_cc (mpc_function* function, mpc_srcptr z, mpc_srcptr x,
639 mpc_ptr got, mpc_ptr expected)
641 known_signs_t ks = {1, 1};
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))
648 printf ("Reuse error for %s(z, z, x) for\n", function->name);
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))
661 printf ("Reuse error for %s(x, z, x) for\n", function->name);
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))
674 printf ("Reuse error for %s(x, x, x) for\n", function->name);
684 reuse_cccc (mpc_function* function, mpc_srcptr z, mpc_srcptr x, mpc_srcptr y,
685 mpc_ptr got, mpc_ptr expected)
687 known_signs_t ks = {1, 1};
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))
694 printf ("Reuse error for %s(z, z, x, y) for\n", function->name);
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))
709 printf ("Reuse error for %s(x, z, x, y) for\n", function->name);
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))
724 printf ("Reuse error for %s(y, z, x, y) for\n", function->name);
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))
739 printf ("Reuse error for %s(x, x, x, x) for\n", function->name);
749 reuse_ccu (mpc_function* function, mpc_srcptr z, unsigned long ul,
750 mpc_ptr got, mpc_ptr expected)
752 known_signs_t ks = {1, 1};
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))
759 printf ("Reuse error for %s(z, z, n) for\n", function->name);
761 printf ("n=%lu\n", ul);
770 reuse_cuc (mpc_function* function, unsigned long ul, mpc_srcptr z,
771 mpc_ptr got, mpc_ptr expected)
773 known_signs_t ks = {1, 1};
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))
780 printf ("Reuse error for %s(z, n, z) for\n", function->name);
781 printf ("n=%lu\n", ul);
791 reuse_ccs (mpc_function* function, mpc_srcptr z, long lo,
792 mpc_ptr got, mpc_ptr expected)
794 known_signs_t ks = {1, 1};
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))
801 printf ("Reuse error for %s(z, z, n) for\n", function->name);
803 printf ("n=%ld\n", lo);
812 reuse_cci (mpc_function* function, mpc_srcptr z, int i,
813 mpc_ptr got, mpc_ptr expected)
815 known_signs_t ks = {1, 1};
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))
822 printf ("Reuse error for %s(z, z, n) for\n", function->name);
824 printf ("n=%d\n", i);
833 reuse_cuuc (mpc_function* function, unsigned long ul1, unsigned long ul2,
834 mpc_srcptr z, mpc_ptr got, mpc_ptr expected)
836 known_signs_t ks = {1, 1};
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))
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);
855 /* helper functions for iterating over mpfr rounding modes */
857 first_rnd_mode (void)
863 next_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 */
875 /* return invalid guard value in mpfr_rnd_t */
876 #if MPFR_VERSION_MAJOR < 3
879 return MPFR_RNDA; /* valid rounding type, but not (yet) used in mpc */
885 is_valid_rnd_mode (mpfr_rnd_t curr)
886 /* returns 1 if curr is a valid rounding mode, and 0otherwise */
888 if ( curr == GMP_RNDN || curr == GMP_RNDZ
889 || curr == GMP_RNDU || curr == GMP_RNDD)
895 /* tgeneric(prec_min, prec_max, step, exp_max) checks rounding with random
897 - with precision ranging from prec_min to prec_max with an increment of
899 - with exponent between -exp_max and exp_max.
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). */
905 tgeneric (mpc_function function, mpfr_prec_t prec_min,
906 mpfr_prec_t prec_max, mpfr_prec_t step, mpfr_exp_t exp_max)
908 unsigned long ul1 = 0, ul2 = 0;
912 mpc_t z1, z2, z3, z4, z5, zzzz, zzzz2;
914 mpfr_rnd_t rnd_re, rnd_im, rnd2_re, rnd2_im;
917 int special, special_cases;
919 mpc_init2 (z1, prec_max);
920 switch (function.type)
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);
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);
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);
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);
953 mpc_init2 (z2, prec_max);
954 mpc_init2 (z3, prec_max);
955 mpc_init2 (zzzz, 4*prec_max);
959 mpc_init2 (z2, prec_max);
960 mpc_init2 (z3, prec_max);
961 mpc_init2 (zzzz, 4*prec_max);
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);
975 mpc_init2 (z2, prec_max);
976 mpc_init2 (z3, prec_max);
977 mpc_init2 (zzzz, 4*prec_max);
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)
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. */
996 /* probability of one zero part in 256th (25 is almost 10%) */
997 const unsigned int zero_probability = special != 0 ? 0 : 25;
999 mpc_set_prec (z1, prec);
1000 test_default_random (z1, exp_min, exp_max, 128, zero_probability);
1002 switch (function.type)
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);
1013 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
1016 mpfr_set_inf (mpc_realref (z1), +1);
1019 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
1022 mpfr_set_inf (mpc_imagref (z1), -1);
1025 mpfr_set_ui (mpc_realref (z2), 0, GMP_RNDN);
1028 mpfr_set_inf (mpc_realref (z2), -1);
1031 mpfr_set_ui (mpc_imagref (z2), 0, GMP_RNDN);
1034 mpfr_set_inf (mpc_imagref (z2), +1);
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);
1048 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
1051 mpfr_set_inf (mpc_realref (z1), +1);
1054 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
1057 mpfr_set_inf (mpc_imagref (z1), -1);
1060 mpfr_set_ui (mpc_realref (z2), 0, GMP_RNDN);
1063 mpfr_set_inf (mpc_realref (z2), -1);
1066 mpfr_set_ui (mpc_imagref (z2), 0, GMP_RNDN);
1069 mpfr_set_inf (mpc_imagref (z2), +1);
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);
1081 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
1084 mpfr_set_inf (mpc_realref (z1), +1);
1087 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
1090 mpfr_set_inf (mpc_imagref (z1), -1);
1095 mpc_set_prec (z2, 128);
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);
1106 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
1109 mpfr_set_inf (mpc_realref (z1), +1);
1112 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
1115 mpfr_set_inf (mpc_imagref (z1), -1);
1123 mpc_set_prec (z2, 128);
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);
1136 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
1139 mpfr_set_inf (mpc_realref (z1), +1);
1142 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
1145 mpfr_set_inf (mpc_imagref (z1), -1);
1156 mpc_set_prec (z2, 128);
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);
1167 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
1170 mpfr_set_inf (mpc_realref (z1), +1);
1173 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
1176 mpfr_set_inf (mpc_imagref (z1), -1);
1184 mpc_set_prec (z2, 128);
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);
1195 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
1198 mpfr_set_inf (mpc_realref (z1), +1);
1201 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
1204 mpfr_set_inf (mpc_imagref (z1), -1);
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);
1221 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
1224 mpfr_set_inf (mpc_realref (z1), +1);
1227 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
1230 mpfr_set_inf (mpc_imagref (z1), -1);
1233 mpfr_set_ui (x1, 0, GMP_RNDN);
1236 mpfr_set_inf (x1, +1);
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);
1250 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
1253 mpfr_set_inf (mpc_realref (z1), +1);
1256 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
1259 mpfr_set_inf (mpc_imagref (z1), -1);
1265 mpc_set_prec (z2, prec);
1266 mpc_set_prec (z3, prec);
1267 mpc_set_prec (zzzz, 4*prec);
1271 mpfr_set_ui (mpc_realref (z1), 0, GMP_RNDN);
1274 mpfr_set_inf (mpc_realref (z1), +1);
1277 mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
1280 mpfr_set_inf (mpc_imagref (z1), -1);
1285 for (rnd_re = first_rnd_mode (); is_valid_rnd_mode (rnd_re); rnd_re = next_rnd_mode (rnd_re))
1286 switch (function.type)
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);
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);
1301 tgeneric_fc (&function, z1, x1, xxxx, x2, rnd_re);
1302 reuse_fc (&function, z1, z2, x1);
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);
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);
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);
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);
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);
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);
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);
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);
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);
1361 printf ("tgeneric not yet implemented for this kind of"
1368 switch (function.type)