Import Upstream version 0.8.2
[platform/upstream/mpc.git] / tests / tgeneric.c
1 /* File for generic tests.
2
3 Copyright (C) 2008, 2009 Philippe Th\'eveny, Andreas Enge, Paul Zimmermann
4
5 This file is part of the MPC Library.
6
7 The MPC Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or (at your
10 option) any later version.
11
12 The MPC Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with the MPC Library; see the file COPYING.LIB.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 MA 02111-1307, USA. */
21
22 /* #include <stdlib.h> */
23
24 #include "mpc-tests.h"
25
26 /* Warning: unlike the MPFR macro (defined in mpfr-impl.h), this one returns
27    true when b is singular */
28 #define MPFR_CAN_ROUND(b,err,prec,rnd)                                  \
29   (mpfr_zero_p (b) || mpfr_inf_p (b)                                    \
30    || mpfr_can_round (b, (long)mpfr_get_prec (b) - (err), (rnd),        \
31                       GMP_RNDZ, (prec) + ((rnd)==GMP_RNDN)))
32
33 static void
34 tgeneric_cc (mpc_function *function, mpc_ptr op, mpc_ptr rop,
35              mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
36 {
37   known_signs_t ks = {1, 1};
38
39   /* We compute the result with four times the precision and check whether the
40      rounding is correct. Error reports in this part of the algorithm might
41      still be wrong, though, since there are two consecutive roundings (but we
42      try to avoid them).  */
43   function->pointer.CC (rop4, op, rnd);
44   function->pointer.CC (rop, op, rnd);
45
46   /* can't use the mpfr_can_round function when argument is singular,
47      use a custom macro instead. */
48   if (MPFR_CAN_ROUND (MPC_RE (rop4), 1, MPFR_PREC (MPC_RE (rop)),
49                       MPC_RND_RE (rnd))
50       && MPFR_CAN_ROUND (MPC_IM (rop4), 1, MPFR_PREC (MPC_IM (rop)),
51                          MPC_RND_IM (rnd)))
52     mpc_set (rop4rnd, rop4, rnd);
53   else
54     /* avoid double rounding error */
55     return;
56
57   if (same_mpc_value (rop, rop4rnd, ks))
58     return;
59
60   /* rounding failed */
61   printf ("Rounding in %s might be incorrect for\n", function->name);
62   OUT (op);
63
64   printf ("with rounding mode (%s, %s)",
65           mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
66           mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
67
68   printf ("\n%s                     gives ", function->name);
69   OUT (rop);
70   printf ("%s quadruple precision gives ", function->name);
71   OUT (rop4);
72   printf ("and is rounded to                  ");
73   OUT (rop4rnd);
74
75   exit (1);
76 }
77
78 static void
79 tgeneric_fc (mpc_function *function, mpc_ptr op, mpfr_ptr rop,
80              mpfr_ptr rop4, mpfr_ptr rop4rnd, mpfr_rnd_t rnd)
81 {
82   function->pointer.FC (rop4, op, rnd);
83   function->pointer.FC (rop, op, rnd);
84   if (MPFR_CAN_ROUND (rop4, 1, MPFR_PREC (rop), rnd))
85     mpfr_set (rop4rnd, rop4, rnd);
86   else
87     return;
88
89   if (same_mpfr_value (rop, rop4rnd, 1))
90     return;
91
92   printf ("Rounding in %s might be incorrect for\n", function->name);
93   OUT (op);
94   printf ("with rounding mode %s", mpfr_print_rnd_mode (rnd));
95
96   printf ("\n%s                     gives ", function->name);
97   MPFR_OUT (rop);
98   printf ("%s quadruple precision gives ", function->name);
99   MPFR_OUT (rop4);
100   printf ("and is rounded to                  ");
101   MPFR_OUT (rop4rnd);
102
103   exit (1);
104 }
105
106 static void
107 tgeneric_cfc (mpc_function *function, mpfr_ptr op1, mpc_ptr op2,
108               mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
109 {
110   known_signs_t ks = {1, 1};
111
112   function->pointer.CFC (rop4, op1, op2, rnd);
113   function->pointer.CFC (rop, op1, op2, rnd);
114   if (MPFR_CAN_ROUND (MPC_RE (rop4), 1,  MPFR_PREC (MPC_RE (rop)),
115                       MPC_RND_RE (rnd))
116       && MPFR_CAN_ROUND (MPC_IM (rop4), 1,  MPFR_PREC (MPC_IM (rop)),
117                          MPC_RND_IM (rnd)))
118     mpc_set (rop4rnd, rop4, rnd);
119   else
120     return;
121
122   if (same_mpc_value (rop, rop4rnd, ks))
123     return;
124
125   printf ("Rounding in %s might be incorrect for\n", function->name);
126   MPFR_OUT (op1);
127   OUT (op2);
128   printf ("with rounding mode (%s, %s)",
129           mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
130           mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
131
132   printf ("\n%s                     gives ", function->name);
133   OUT (rop);
134   printf ("%s quadruple precision gives ", function->name);
135   OUT (rop4);
136   printf ("and is rounded to                  ");
137   OUT (rop4rnd);
138
139   exit (1);
140 }
141
142 static void
143 tgeneric_ccf (mpc_function *function, mpc_ptr op1, mpfr_ptr op2,
144               mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
145 {
146   known_signs_t ks = {1, 1};
147
148   function->pointer.CCF (rop4, op1, op2, rnd);
149   function->pointer.CCF (rop, op1, op2, rnd);
150   if (MPFR_CAN_ROUND (MPC_RE (rop4), 1,  MPFR_PREC (MPC_RE (rop)),
151                       MPC_RND_RE (rnd))
152       && MPFR_CAN_ROUND (MPC_IM (rop4), 1,  MPFR_PREC (MPC_IM (rop)),
153                          MPC_RND_IM (rnd)))
154     mpc_set (rop4rnd, rop4, rnd);
155   else
156     return;
157
158   if (same_mpc_value (rop, rop4rnd, ks))
159     return;
160
161   printf ("Rounding in %s might be incorrect for\n", function->name);
162   OUT (op1);
163   MPFR_OUT (op2);
164   printf ("with rounding mode (%s, %s)",
165           mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
166           mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
167
168   printf ("\n%s                     gives ", function->name);
169   OUT (rop);
170   printf ("%s quadruple precision gives ", function->name);
171   OUT (rop4);
172   printf ("and is rounded to                  ");
173   OUT (rop4rnd);
174
175   exit (1);
176 }
177
178 static void
179 tgeneric_ccc (mpc_function *function, mpc_ptr op1, mpc_ptr op2,
180               mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
181 {
182   known_signs_t ks = {1, 1};
183
184   /* We compute the result with four times the precision and check whether the
185      rounding is correct. Error reports in this part of the algorithm might
186      still be wrong, though, since there are two consecutive roundings (but we
187      try to avoid them).  */
188   function->pointer.CCC (rop4, op1, op2, rnd);
189   function->pointer.CCC (rop, op1, op2, rnd);
190
191   /* can't use mpfr_can_round when argument is singular */
192   if (MPFR_CAN_ROUND (MPC_RE (rop4), 1, MPFR_PREC (MPC_RE (rop)),
193                       MPC_RND_RE (rnd))
194       && MPFR_CAN_ROUND (MPC_IM (rop4), 1, MPFR_PREC (MPC_IM (rop)),
195                          MPC_RND_IM (rnd)))
196     mpc_set (rop4rnd, rop4, rnd);
197   else
198     /* avoid double rounding error */
199     return;
200
201   if (same_mpc_value (rop, rop4rnd, ks))
202     return;
203
204   /* rounding failed */
205   printf ("Rounding in %s might be incorrect for\n", function->name);
206   OUT (op1);
207   OUT (op2);
208   printf ("with rounding mode (%s, %s)",
209           mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
210           mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
211
212   printf ("\n%s                     gives ", function->name);
213   OUT (rop);
214   printf ("%s quadruple precision gives ", function->name);
215   OUT (rop4);
216   printf ("and is rounded to                  ");
217   OUT (rop4rnd);
218
219   exit (1);
220 }
221
222 static void
223 tgeneric_ccu (mpc_function *function, mpc_ptr op1, unsigned long int op2,
224               mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
225 {
226   known_signs_t ks = {1, 1};
227
228   function->pointer.CCU (rop4, op1, op2, rnd);
229   function->pointer.CCU (rop, op1, op2, rnd);
230   if (MPFR_CAN_ROUND (MPC_RE (rop4), 1,  MPFR_PREC (MPC_RE (rop)),
231                       MPC_RND_RE (rnd))
232       && MPFR_CAN_ROUND (MPC_IM (rop4), 1,  MPFR_PREC (MPC_IM (rop)),
233                          MPC_RND_IM (rnd)))
234     mpc_set (rop4rnd, rop4, rnd);
235   else
236     return;
237
238   if (same_mpc_value (rop, rop4rnd, ks))
239     return;
240
241   printf ("Rounding in %s might be incorrect for\n", function->name);
242   OUT (op1);
243   printf ("op2=%lu\n", op2);
244   printf ("with rounding mode (%s, %s)",
245           mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
246           mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
247
248   printf ("\n%s                     gives ", function->name);
249   OUT (rop);
250   printf ("%s quadruple precision gives ", function->name);
251   OUT (rop4);
252   printf ("and is rounded to                  ");
253   OUT (rop4rnd);
254
255   exit (1);
256 }
257
258 static void
259 tgeneric_cuc (mpc_function *function, unsigned long int op1, mpc_ptr op2,
260               mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
261 {
262   known_signs_t ks = {1, 1};
263
264   function->pointer.CUC (rop4, op1, op2, rnd);
265   function->pointer.CUC (rop, op1, op2, rnd);
266   if (MPFR_CAN_ROUND (MPC_RE (rop4), 1,  MPFR_PREC (MPC_RE (rop)),
267                       MPC_RND_RE (rnd))
268       && MPFR_CAN_ROUND (MPC_IM (rop4), 1,  MPFR_PREC (MPC_IM (rop)),
269                          MPC_RND_IM (rnd)))
270     mpc_set (rop4rnd, rop4, rnd);
271   else
272     return;
273
274   if (same_mpc_value (rop, rop4rnd, ks))
275     return;
276
277   printf ("Rounding in %s might be incorrect for\n", function->name);
278   printf ("op1=%lu\n", op1);
279   OUT (op2);
280   printf ("with rounding mode (%s, %s)",
281           mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
282           mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
283
284   printf ("\n%s                     gives ", function->name);
285   OUT (rop);
286   printf ("%s quadruple precision gives ", function->name);
287   OUT (rop4);
288   printf ("and is rounded to                  ");
289   OUT (rop4rnd);
290
291   exit (1);
292 }
293
294 static void
295 tgeneric_ccs (mpc_function *function, mpc_ptr op1, long int op2,
296               mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
297 {
298   known_signs_t ks = {1, 1};
299
300   function->pointer.CCS (rop4, op1, op2, rnd);
301   function->pointer.CCS (rop, op1, op2, rnd);
302   if (MPFR_CAN_ROUND (MPC_RE (rop4), 1,  MPFR_PREC (MPC_RE (rop)),
303                       MPC_RND_RE (rnd))
304       && MPFR_CAN_ROUND (MPC_IM (rop4), 1,  MPFR_PREC (MPC_IM (rop)),
305                          MPC_RND_IM (rnd)))
306     mpc_set (rop4rnd, rop4, rnd);
307   else
308     return;
309
310   if (same_mpc_value (rop, rop4rnd, ks))
311     return;
312
313   printf ("Rounding in %s might be incorrect for\n", function->name);
314   OUT (op1);
315   printf ("op2=%ld\n", op2);
316   printf ("with rounding mode (%s, %s)",
317           mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
318           mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
319
320   printf ("\n%s                     gives ", function->name);
321   OUT (rop);
322   printf ("%s quadruple precision gives ", function->name);
323   OUT (rop4);
324   printf ("and is rounded to                  ");
325   OUT (rop4rnd);
326
327   exit (1);
328 }
329
330
331 static void
332 tgeneric_cci (mpc_function *function, mpc_ptr op1, int op2,
333               mpc_ptr rop, mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
334 {
335   known_signs_t ks = {1, 1};
336
337   function->pointer.CCI (rop4, op1, op2, rnd);
338   function->pointer.CCI (rop, op1, op2, rnd);
339   if (MPFR_CAN_ROUND (MPC_RE (rop4), 1,  MPFR_PREC (MPC_RE (rop)),
340                       MPC_RND_RE (rnd))
341       && MPFR_CAN_ROUND (MPC_IM (rop4), 1,  MPFR_PREC (MPC_IM (rop)),
342                          MPC_RND_IM (rnd)))
343     mpc_set (rop4rnd, rop4, rnd);
344   else
345     return;
346
347   if (same_mpc_value (rop, rop4rnd, ks))
348     return;
349
350   printf ("Rounding in %s might be incorrect for\n", function->name);
351   OUT (op1);
352   printf ("op2=%d\n", op2);
353   printf ("with rounding mode (%s, %s)",
354           mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
355           mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
356
357   printf ("\n%s                     gives ", function->name);
358   OUT (rop);
359   printf ("%s quadruple precision gives ", function->name);
360   OUT (rop4);
361   printf ("and is rounded to                  ");
362   OUT (rop4rnd);
363
364   exit (1);
365 }
366
367 static void
368 tgeneric_cuuc (mpc_function *function, unsigned long int op1,
369                unsigned long int op2, mpc_ptr op3, mpc_ptr rop,
370                mpc_ptr rop4, mpc_ptr rop4rnd, mpc_rnd_t rnd)
371 {
372   known_signs_t ks = {1, 1};
373
374   function->pointer.CUUC (rop4, op1, op2, op3, rnd);
375   function->pointer.CUUC (rop, op1, op2, op3, rnd);
376   if (MPFR_CAN_ROUND (MPC_RE (rop4), 1,  MPFR_PREC (MPC_RE (rop)),
377                       MPC_RND_RE (rnd))
378       && MPFR_CAN_ROUND (MPC_IM (rop4), 1,  MPFR_PREC (MPC_IM (rop)),
379                          MPC_RND_IM (rnd)))
380     mpc_set (rop4rnd, rop4, rnd);
381   else
382     return;
383
384   if (same_mpc_value (rop, rop4rnd, ks))
385     return;
386
387   printf ("Rounding in %s might be incorrect for\n", function->name);
388   printf ("op1=%lu\n", op1);
389   printf ("op2=%lu\n", op2);
390   OUT (op3);
391   printf ("with rounding mode (%s, %s)",
392           mpfr_print_rnd_mode (MPC_RND_RE (rnd)),
393           mpfr_print_rnd_mode (MPC_RND_IM (rnd)));
394
395   printf ("\n%s                     gives ", function->name);
396   OUT (rop);
397   printf ("%s quadruple precision gives ", function->name);
398   OUT (rop4);
399   printf ("and is rounded to                  ");
400   OUT (rop4rnd);
401
402   exit (1);
403 }
404
405
406 /* Test parameter reuse: the function should not use its output parameter in
407    internal computations. */
408 static void
409 reuse_cc (mpc_function* function, mpc_srcptr z, mpc_ptr got, mpc_ptr expected)
410 {
411   known_signs_t ks = {1, 1};
412
413   mpc_set (got, z, MPC_RNDNN); /* exact */
414   function->pointer.CC (expected, z, MPC_RNDNN);
415   function->pointer.CC (got, got, MPC_RNDNN);
416   if (!same_mpc_value (got, expected, ks))
417     {
418       printf ("Error for %s(z, z) for\n", function->name);
419       OUT (z);
420       OUT (expected);
421       OUT (got);
422
423       exit (1);
424     }
425 }
426
427 static void
428 reuse_fc (mpc_function* function, mpc_ptr z, mpc_ptr x, mpfr_ptr expected)
429 {
430   mpc_set (x, z, MPC_RNDNN); /* exact */
431   function->pointer.FC (expected, z, GMP_RNDN);
432   function->pointer.FC (MPC_RE (x), x, GMP_RNDN);
433   if (!same_mpfr_value (MPC_RE (x), expected, 1))
434     {
435       mpfr_t got;
436       got[0] = MPC_RE(x)[0]; /* display sensible name */
437       printf ("Error for %s(MPC_RE(z), z) for\n", function->name);
438       OUT (z);
439       MPFR_OUT (expected);
440       MPFR_OUT (got);
441
442       exit (1);
443     }
444   mpc_set (x, z, MPC_RNDNN); /* exact */
445   function->pointer.FC (MPC_IM (x), x, GMP_RNDN);
446   if (!same_mpfr_value (MPC_IM (x), expected, 1))
447     {
448       mpfr_t got;
449       got[0] = MPC_IM(x)[0]; /* display sensible name */
450       printf ("Error for %s(MPC_IM(z), z) for \n", function->name);
451       OUT (z);
452       MPFR_OUT (expected);
453       MPFR_OUT (got);
454
455       exit (1);
456     }
457 }
458
459 static void
460 reuse_cfc (mpc_function* function, mpc_srcptr z, mpfr_srcptr x, mpc_ptr got,
461            mpc_ptr expected)
462 {
463   known_signs_t ks = {1, 1};
464
465   mpc_set (got, z, MPC_RNDNN); /* exact */
466   function->pointer.CFC (expected, x, z, MPC_RNDNN);
467   function->pointer.CFC (got, x, got, MPC_RNDNN);
468   if (!same_mpc_value (got, expected, ks))
469     {
470       printf ("Error for %s(z, x, z) for\n", function->name);
471       MPFR_OUT (x);
472       OUT (z);
473       OUT (expected);
474       OUT (got);
475
476       exit (1);
477     }
478 }
479
480 static void
481 reuse_ccf (mpc_function* function, mpc_srcptr z, mpfr_srcptr x, mpc_ptr got,
482            mpc_ptr expected)
483 {
484   known_signs_t ks = {1, 1};
485
486   mpc_set (got, z, MPC_RNDNN); /* exact */
487   function->pointer.CCF (expected, z, x, MPC_RNDNN);
488   function->pointer.CCF (got, got, x, MPC_RNDNN);
489   if (!same_mpc_value (got, expected, ks))
490     {
491       printf ("Error for %s(z, z, x) for\n", function->name);
492       OUT (z);
493       MPFR_OUT (x);
494       OUT (expected);
495       OUT (got);
496
497       exit (1);
498     }
499 }
500
501 static void
502 reuse_ccc (mpc_function* function, mpc_srcptr z, mpc_srcptr x,
503            mpc_ptr got, mpc_ptr expected)
504 {
505   known_signs_t ks = {1, 1};
506
507   mpc_set (got, z, MPC_RNDNN); /* exact */
508   function->pointer.CCC (expected, z, x, MPC_RNDNN);
509   function->pointer.CCC (got, got, x, MPC_RNDNN);
510   if (!same_mpc_value (got, expected, ks))
511     {
512       printf ("Error for %s(z, z, x) for\n", function->name);
513       OUT (z);
514       OUT (x);
515       OUT (expected);
516       OUT (got);
517
518       exit (1);
519     }
520   mpc_set (got, x, MPC_RNDNN); /* exact */
521   function->pointer.CCC (expected, z, x, MPC_RNDNN);
522   function->pointer.CCC (got, z, got, MPC_RNDNN);
523   if (!same_mpc_value (got, expected, ks))
524     {
525       printf ("Error for %s(x, z, x) for\n", function->name);
526       OUT (z);
527       OUT (x);
528       OUT (expected);
529       OUT (got);
530
531       exit (1);
532     }
533   mpc_set (got, x, MPC_RNDNN); /* exact */
534   function->pointer.CCC (expected, x, x, MPC_RNDNN);
535   function->pointer.CCC (got, got, got, MPC_RNDNN);
536   if (!same_mpc_value (got, expected, ks))
537     {
538       printf ("Error for %s(x, x, x) for\n", function->name);
539       OUT (x);
540       OUT (expected);
541       OUT (got);
542
543       exit (1);
544     }
545 }
546
547 static void
548 reuse_ccu (mpc_function* function, mpc_srcptr z, unsigned long ul,
549            mpc_ptr got, mpc_ptr expected)
550 {
551   known_signs_t ks = {1, 1};
552
553   mpc_set (got, z, MPC_RNDNN); /* exact */
554   function->pointer.CCU (expected, z, ul, MPC_RNDNN);
555   function->pointer.CCU (got, got, ul, MPC_RNDNN);
556   if (!same_mpc_value (got, expected, ks))
557     {
558       printf ("Error for %s(z, z, n) for\n", function->name);
559       OUT (z);
560       printf ("n=%lu\n", ul);
561       OUT (expected);
562       OUT (got);
563
564       exit (1);
565     }
566 }
567
568 static void
569 reuse_cuc (mpc_function* function, unsigned long ul, mpc_srcptr z,
570            mpc_ptr got, mpc_ptr expected)
571 {
572   known_signs_t ks = {1, 1};
573
574   mpc_set (got, z, MPC_RNDNN); /* exact */
575   function->pointer.CUC (expected, ul, z,MPC_RNDNN);
576   function->pointer.CUC (got, ul, got, MPC_RNDNN);
577   if (!same_mpc_value (got, expected, ks))
578     {
579       printf ("Error for %s(z, n, z) for\n", function->name);
580       printf ("n=%lu\n", ul);
581       OUT (z);
582       OUT (expected);
583       OUT (got);
584
585       exit (1);
586     }
587 }
588
589 static void
590 reuse_ccs (mpc_function* function, mpc_srcptr z, long lo,
591            mpc_ptr got, mpc_ptr expected)
592 {
593   known_signs_t ks = {1, 1};
594
595   mpc_set (got, z, MPC_RNDNN); /* exact */
596   function->pointer.CCS (expected, z, lo, MPC_RNDNN);
597   function->pointer.CCS (got, got, lo, MPC_RNDNN);
598   if (!same_mpc_value (got, expected, ks))
599     {
600       printf ("Error for %s(z, z, n) for\n", function->name);
601       OUT (z);
602       printf ("n=%ld\n", lo);
603       OUT (expected);
604       OUT (got);
605
606       exit (1);
607     }
608 }
609
610 static void
611 reuse_cci (mpc_function* function, mpc_srcptr z, int i,
612            mpc_ptr got, mpc_ptr expected)
613 {
614   known_signs_t ks = {1, 1};
615
616   mpc_set (got, z, MPC_RNDNN); /* exact */
617   function->pointer.CCI (expected, z, i, MPC_RNDNN);
618   function->pointer.CCI (got, got, i, MPC_RNDNN);
619   if (!same_mpc_value (got, expected, ks))
620     {
621       printf ("Error for %s(z, z, n) for\n", function->name);
622       OUT (z);
623       printf ("n=%d\n", i);
624       OUT (expected);
625       OUT (got);
626
627       exit (1);
628     }
629 }
630
631 static void
632 reuse_cuuc (mpc_function* function, unsigned long ul1, unsigned long ul2,
633             mpc_srcptr z, mpc_ptr got, mpc_ptr expected)
634 {
635   known_signs_t ks = {1, 1};
636
637   mpc_set (got, z, MPC_RNDNN); /* exact */
638   function->pointer.CUUC (expected, ul1, ul2, z,MPC_RNDNN);
639   function->pointer.CUUC (got, ul1, ul2, got, MPC_RNDNN);
640   if (!same_mpc_value (got, expected, ks))
641     {
642       printf ("Error for %s(z, m, n, z) for\n", function->name);
643       printf ("m=%lu\n", ul1);
644       printf ("n=%lu\n", ul2);
645       OUT (z);
646       OUT (expected);
647       OUT (got);
648
649       exit (1);
650     }
651 }
652
653
654 /* tgeneric(prec_min, prec_max, step, exp_max) checks rounding with random
655    numbers:
656    - with precision ranging from prec_min to prec_max with an increment of
657    step,
658    - with exponent between -exp_max and exp_max.
659
660    It also checks parameter reuse (it is assumed here that either two mpc_t
661    variables are equal or they are different, in the sense that the real part
662    of one of them cannot be the imaginary part of the other). */
663 void
664 tgeneric (mpc_function function, mpfr_prec_t prec_min,
665           mpfr_prec_t prec_max, mpfr_prec_t step, mp_exp_t exp_max)
666 {
667   unsigned long ul1 = 0, ul2 = 0;
668   long lo = 0;
669   int i = 0;
670   mpfr_t x1, x2, xxxx;
671   mpc_t  z1, z2, z3, z4, zzzz;
672
673   mpfr_rnd_t rnd_re;
674   mpfr_rnd_t rnd_im;
675   mpfr_prec_t prec;
676   mp_exp_t exp_min;
677   int special, special_cases;
678
679   mpc_init2 (z1, prec_max);
680   switch (function.type)
681     {
682     case CCC:
683       mpc_init2 (z2, prec_max);
684       mpc_init2 (z3, prec_max);
685       mpc_init2 (z4, prec_max);
686       mpc_init2 (zzzz, 4*prec_max);
687       special_cases = 4;
688       break;
689     case FC:
690       mpfr_init2 (x1, prec_max);
691       mpfr_init2 (x2, prec_max);
692       mpfr_init2 (xxxx, 4*prec_max);
693       mpc_init2 (z2, prec_max);
694       special_cases = 2;
695       break;
696     case CCF: case CFC:
697       mpfr_init2 (x1, prec_max);
698       mpc_init2 (z2, prec_max);
699       mpc_init2 (z3, prec_max);
700       mpc_init2 (zzzz, 4*prec_max);
701       special_cases = 3;
702       break;
703     case CCI: case CCS:
704     case CCU: case CUC:
705       mpc_init2 (z2, prec_max);
706       mpc_init2 (z3, prec_max);
707       mpc_init2 (zzzz, 4*prec_max);
708       special_cases = 3;
709       break;
710     case CUUC:
711       mpc_init2 (z2, prec_max);
712       mpc_init2 (z3, prec_max);
713       mpc_init2 (zzzz, 4*prec_max);
714       special_cases = 2;
715       break;
716     case CC:
717     default:
718       mpc_init2 (z2, prec_max);
719       mpc_init2 (z3, prec_max);
720       mpc_init2 (zzzz, 4*prec_max);
721       special_cases = 2;
722     }
723
724   exp_min = mpfr_get_emin ();
725   if (exp_max <= 0)
726     exp_max = mpfr_get_emax ();
727   else if (exp_max > mpfr_get_emax ())
728     exp_max = mpfr_get_emax();
729   if (-exp_max > exp_min)
730     exp_min = - exp_max;
731
732   if (step < 1)
733     step = 1;
734
735   for (prec = prec_min, special = 0;
736        prec <= prec_max && special <= special_cases;
737        prec+=step, special += (prec == prec_max ? 1 : 0))
738     {
739       /* when prec == prec_max, test functions with pure real/pure imaginary
740          parameters */
741
742       /* probability of one zero part in 256th (25 is almost 10%) */
743       const unsigned int zero_probability = special != 0 ? 0 : 25;
744
745       mpc_set_prec (z1, prec);
746       test_default_random (z1, exp_min, exp_max, 128, zero_probability);
747
748       switch (function.type)
749         {
750         case CCC:
751           mpc_set_prec (z2, prec);
752           test_default_random (z2, exp_min, exp_max, 128, zero_probability);
753           mpc_set_prec (z3, prec);
754           mpc_set_prec (z4, prec);
755           mpc_set_prec (zzzz, 4*prec);
756           switch (special)
757             {
758             case 1:
759               mpfr_set_ui (MPC_RE (z1), 0, GMP_RNDN);
760               break;
761             case 2:
762               mpfr_set_ui (MPC_IM (z1), 0, GMP_RNDN);
763               break;
764             case 3:
765               mpfr_set_ui (MPC_RE (z2), 0, GMP_RNDN);
766               break;
767             case 4:
768               mpfr_set_ui (MPC_IM (z2), 0, GMP_RNDN);
769               break;
770             }
771           break;
772         case FC:
773           mpc_set_prec (z2, prec);
774           mpfr_set_prec (x1, prec);
775           mpfr_set_prec (x2, prec);
776           mpfr_set_prec (xxxx, 4*prec);
777           switch (special)
778             {
779             case 1:
780               mpfr_set_ui (MPC_RE (z1), 0, GMP_RNDN);
781               break;
782             case 2:
783               mpfr_set_ui (MPC_IM (z1), 0, GMP_RNDN);
784               break;
785             }
786           break;
787         case CCU: case CUC:
788           mpc_set_prec (z2, 128);
789           do {
790             test_default_random (z2, 0, 64, 128, zero_probability);
791           } while (!mpfr_fits_ulong_p (MPC_RE (z2), GMP_RNDN));
792           ul1 = mpfr_get_ui (MPC_RE(z2), GMP_RNDN);
793           mpc_set_prec (z2, prec);
794           mpc_set_prec (z3, prec);
795           mpc_set_prec (zzzz, 4*prec);
796           switch (special)
797             {
798             case 1:
799               mpfr_set_ui (MPC_RE (z1), 0, GMP_RNDN);
800               break;
801             case 2:
802               mpfr_set_ui (MPC_IM (z1), 0, GMP_RNDN);
803               break;
804             case 3:
805               ul1 = 0;
806               break;
807             }
808           break;
809         case CUUC:
810           mpc_set_prec (z2, 128);
811           do {
812             test_default_random (z2, 0, 64, 128, zero_probability);
813           } while (!mpfr_fits_ulong_p (MPC_RE (z2), GMP_RNDN)
814                    ||!mpfr_fits_ulong_p (MPC_IM (z2), GMP_RNDN));
815           ul1 = mpfr_get_ui (MPC_RE(z2), GMP_RNDN);
816           ul2 = mpfr_get_ui (MPC_IM(z2), GMP_RNDN);
817           mpc_set_prec (z2, prec);
818           mpc_set_prec (z3, prec);
819           mpc_set_prec (zzzz, 4*prec);
820           switch (special)
821             {
822             case 1:
823               mpfr_set_ui (MPC_RE (z1), 0, GMP_RNDN);
824               break;
825             case 2:
826               mpfr_set_ui (MPC_IM (z1), 0, GMP_RNDN);
827               break;
828             case 3:
829               ul1 = 0;
830               break;
831             case 4:
832               ul2 = 0;
833               break;
834             }
835           break;
836         case CCS:
837           mpc_set_prec (z2, 128);
838           do {
839             test_default_random (z2, 0, 64, 128, zero_probability);
840           } while (!mpfr_fits_slong_p (MPC_RE (z2), GMP_RNDN));
841           lo = mpfr_get_si (MPC_RE(z2), GMP_RNDN);
842           mpc_set_prec (z2, prec);
843           mpc_set_prec (z3, prec);
844           mpc_set_prec (zzzz, 4*prec);
845           switch (special)
846             {
847             case 1:
848               mpfr_set_ui (MPC_RE (z1), 0, GMP_RNDN);
849               break;
850             case 2:
851               mpfr_set_ui (MPC_IM (z1), 0, GMP_RNDN);
852               break;
853             case 3:
854               lo = 0;
855               break;
856             }
857           break;
858         case CCI:
859           mpc_set_prec (z2, 128);
860           do {
861             test_default_random (z2, 0, 64, 128, zero_probability);
862           } while (!mpfr_fits_slong_p (MPC_RE (z2), GMP_RNDN));
863           i = (int)mpfr_get_si (MPC_RE(z2), GMP_RNDN);
864           mpc_set_prec (z2, prec);
865           mpc_set_prec (z3, prec);
866           mpc_set_prec (zzzz, 4*prec);
867           switch (special)
868             {
869             case 1:
870               mpfr_set_ui (MPC_RE (z1), 0, GMP_RNDN);
871               break;
872             case 2:
873               mpfr_set_ui (MPC_IM (z1), 0, GMP_RNDN);
874               break;
875             case 3:
876               i = 0;
877               break;
878             }
879           break;
880         case CCF: case CFC:
881           mpfr_set_prec (x1, prec);
882           mpfr_set (x1, MPC_RE (z1), GMP_RNDN);
883           test_default_random (z1, exp_min, exp_max, 128, zero_probability);
884           mpc_set_prec (z2, prec);
885           mpc_set_prec (z3, prec);
886           mpc_set_prec (zzzz, 4*prec);
887           switch (special)
888             {
889             case 1:
890               mpfr_set_ui (MPC_RE (z1), 0, GMP_RNDN);
891               break;
892             case 2:
893               mpfr_set_ui (MPC_IM (z1), 0, GMP_RNDN);
894               break;
895             case 3:
896               mpfr_set_ui (x1, 0, GMP_RNDN);
897               break;
898             }
899           break;
900         case CC:
901         default:
902           mpc_set_prec (z2, prec);
903           mpc_set_prec (z3, prec);
904           mpc_set_prec (zzzz, 4*prec);
905           switch (special)
906             {
907             case 1:
908               mpfr_set_ui (MPC_RE (z1), 0, GMP_RNDN);
909               break;
910             case 2:
911               mpfr_set_ui (MPC_IM (z1), 0, GMP_RNDN);
912               break;
913             }
914         }
915
916       for (rnd_re = GMP_RNDN; mpfr_print_rnd_mode (rnd_re); ++rnd_re)
917         switch (function.type)
918           {
919           case CCC:
920             for (rnd_im = GMP_RNDN; mpfr_print_rnd_mode (rnd_im); ++rnd_im)
921               tgeneric_ccc (&function, z1, z2, z3, zzzz, z4,
922                             RNDC (rnd_re, rnd_im));
923             reuse_ccc (&function, z1, z2, z3, z4);
924             break;
925           case FC:
926             tgeneric_fc (&function, z1, x1, xxxx, x2, rnd_re);
927             reuse_fc (&function, z1, z2, x1);
928             break;
929           case CC:
930             for (rnd_im = GMP_RNDN; mpfr_print_rnd_mode (rnd_im); ++rnd_im)
931               tgeneric_cc (&function, z1, z2, zzzz, z3,
932                            RNDC (rnd_re, rnd_im));
933             reuse_cc (&function, z1, z2, z3);
934             break;
935           case CFC:
936             for (rnd_im = GMP_RNDN; mpfr_print_rnd_mode (rnd_im); ++rnd_im)
937               tgeneric_cfc (&function, x1, z1, z2, zzzz, z3,
938                             RNDC (rnd_re, rnd_im));
939             reuse_cfc (&function, z1, x1, z2, z3);
940             break;
941           case CCF:
942             for (rnd_im = GMP_RNDN; mpfr_print_rnd_mode (rnd_im); ++rnd_im)
943               tgeneric_ccf (&function, z1, x1, z2, zzzz, z3,
944                             RNDC (rnd_re, rnd_im));
945             reuse_ccf (&function, z1, x1, z2, z3);
946             break;
947           case CCU:
948             for (rnd_im = GMP_RNDN; mpfr_print_rnd_mode (rnd_im); ++rnd_im)
949               tgeneric_ccu (&function, z1, ul1, z2, zzzz, z3,
950                             RNDC (rnd_re, rnd_im));
951             reuse_ccu (&function, z1, ul1, z2, z3);
952             break;
953           case CUC:
954             for (rnd_im = GMP_RNDN; mpfr_print_rnd_mode (rnd_im); ++rnd_im)
955               tgeneric_cuc (&function, ul1, z1, z2, zzzz, z3,
956                             RNDC (rnd_re, rnd_im));
957             reuse_cuc (&function, ul1, z1, z2, z3);
958             break;
959           case CCS:
960             for (rnd_im = GMP_RNDN; mpfr_print_rnd_mode (rnd_im); ++rnd_im)
961               tgeneric_ccs (&function, z1, lo, z2, zzzz, z3,
962                             RNDC (rnd_re, rnd_im));
963             reuse_ccs (&function, z1, lo, z2, z3);
964             break;
965           case CCI:
966             for (rnd_im = GMP_RNDN; mpfr_print_rnd_mode (rnd_im); ++rnd_im)
967               tgeneric_cci (&function, z1, i, z2, zzzz, z3,
968                             RNDC (rnd_re, rnd_im));
969             reuse_cci (&function, z1, i, z2, z3);
970             break;
971           case CUUC:
972             for (rnd_im = GMP_RNDN; mpfr_print_rnd_mode (rnd_im); ++rnd_im)
973               tgeneric_cuuc (&function, ul1, ul2, z1, z2, zzzz, z3,
974                              RNDC (rnd_re, rnd_im));
975             reuse_cuuc (&function, ul1, ul2, z1, z2, z3);
976             break;
977           default:
978             printf ("tgeneric not yet implemented for this kind of"
979                     "function\n");
980             exit (1);
981           }
982     }
983
984   mpc_clear (z1);
985   switch (function.type)
986     {
987     case CCC:
988       mpc_clear (z2);
989       mpc_clear (z3);
990       mpc_clear (z4);
991       mpc_clear (zzzz);
992       break;
993     case FC:
994       mpc_clear (z2);
995       mpfr_clear (x1);
996       mpfr_clear (x2);
997       mpfr_clear (xxxx);
998       break;
999     case CCF: case CFC:
1000       mpfr_clear (x1);
1001       mpc_clear (z2);
1002       mpc_clear (z3);
1003       mpc_clear (zzzz);
1004       break;
1005     case CUUC:
1006     case CCI: case CCS:
1007     case CCU: case CUC:
1008     case CC:
1009     default:
1010       mpc_clear (z2);
1011       mpc_clear (z3);
1012       mpc_clear (zzzz);
1013     }
1014 }