ulps: Fix long lines
[mathlib.git] / ulps / gen.c
1 #define _XOPEN_SOURCE 600
2
3 #include <assert.h>
4 #include <math.h>
5 #include <stdio.h>
6 #include <string.h>
7
8 #include <gmp.h>
9 #include <mpc.h>
10 #include <mpfr.h>
11
12 #include "basic-complex.h"
13 #include "config.h"
14 #include "gen.h"
15 #include "mytypes.h"
16
17 /*******************************************************************************
18  *                              Real arithmetic
19  ******************************************************************************/
20 static int
21 dom_acos(long double x)
22 {
23         return (x >= -1.0 && x <= 1.0);
24 }
25
26 static int
27 dom_acosh(long double x)
28 {
29         return (x >= 1.0);
30 }
31
32 static int
33 dom_asin(long double x)
34 {
35         return (x >= -1.0 && x <= 1.0);
36 }
37
38 static int
39 dom_asinh(long double x)
40 {
41         return 1;
42 }
43
44 static int
45 dom_atan(long double x)
46 {
47         return 1;
48 }
49
50 static int
51 dom_atan2(long double y, long double x)
52 {
53         return (fpclassify(x) != FP_ZERO);
54 }
55
56 static int
57 dom_atanh(long double x)
58 {
59         return (x > -1.0 && x < 1.0);
60 }
61
62 static int
63 dom_cbrt(long double x)
64 {
65         return 1;
66 }
67
68 static int
69 dom_ceil(long double x)
70 {
71         return 1;
72 }
73
74 static int
75 dom_cos(long double x)
76 {
77         return 1;
78 }
79
80 static int
81 dom_cosh(long double x)
82 {
83         return 1;
84 }
85
86 static int
87 dom_erf(long double x)
88 {
89         return 1;
90 }
91
92 static int
93 dom_erfc(long double x)
94 {
95         return 1;
96 }
97
98 static int
99 dom_exp(long double x)
100 {
101         return 1;
102 }
103
104 static int
105 dom_expm1(long double x)
106 {
107         return 1;
108 }
109
110 static int
111 dom_exp2(long double x)
112 {
113         return 1;
114 }
115
116 static int
117 dom_fabs(long double x)
118 {
119         return 1;
120 }
121
122 static int
123 dom_floor(long double x)
124 {
125         return 1;
126 }
127
128 static int
129 dom_fmod(long double x, long double y)
130 {
131         return (fpclassify(y) != FP_ZERO);
132 }
133
134 static int
135 dom_hypot(long double x, long double y)
136 {
137         return 1;
138 }
139
140 static int
141 dom_j0(long double x)
142 {
143         return 1;
144 }
145
146 static int
147 dom_j1(long double x)
148 {
149         return 1;
150 }
151
152 static int
153 dom_log(long double x)
154 {
155         return (x > 0.0);
156 }
157
158 static int
159 dom_log1p(long double x)
160 {
161         return (x > -1.0);
162 }
163
164 static int
165 dom_log10(long double x)
166 {
167         return (x > 0.0);
168 }
169
170 static int
171 dom_log2(long double x)
172 {
173         return (x > 0.0);
174 }
175
176 static int
177 dom_remainder(long double x, long double y)
178 {
179         return (fpclassify(y) != FP_ZERO);
180 }
181
182 static int
183 dom_rint(long double x)
184 {
185         return 1;
186 }
187
188 static int
189 dom_round(long double x)
190 {
191         return 1;
192 }
193
194 static int
195 dom_sin(long double x)
196 {
197         return 1;
198 }
199
200 static int
201 dom_sinh(long double x)
202 {
203         return 1;
204 }
205
206 static int
207 dom_sqrt(long double x)
208 {
209         return (x >= 0.0);
210 }
211
212 static int
213 dom_tan(long double x)
214 {
215         return (fabs(x - M_PI_2) > 1E-10);
216 }
217
218 static int
219 dom_tanh(long double x)
220 {
221         return 1;
222 }
223
224 static int
225 dom_pow(long double x, long double y)
226 {
227         return (x >= 0.0 || (floor(y) == y));
228 }
229
230 static int
231 dom_tgamma(long double x)
232 {
233         return (x > 0.0 || (floor(x) != x));
234 }
235
236 static int
237 dom_trunc(long double x)
238 {
239         return 1;
240 }
241
242 static int
243 dom_y0(long double x)
244 {
245         return (x > 0.0);
246 }
247
248 static int
249 dom_y1(long double x)
250 {
251         return (x > 0.0);
252 }
253
254 static int
255 dom_yn(long double x, long double y)
256 {
257         return (y > 0.0);
258 }
259
260 /*******************************************************************************
261  *                              Complex arithmetic
262  ******************************************************************************/
263 static int
264 dom_cabs(long double complex z)
265 {
266         return 1;
267 }
268
269 static int
270 dom_cacos(long double complex z)
271 {
272         return 1;
273 }
274
275 static int
276 dom_cacosh(long double complex z)
277 {
278         return 1;
279 }
280
281 static int
282 dom_carg(long double complex z)
283 {
284         /* XXX */
285         return 1;
286 }
287
288 static int
289 dom_casin(long double complex z)
290 {
291         return 1;
292 }
293
294 static int
295 dom_casinh(long double complex z)
296 {
297         return 1;
298 }
299
300 static int
301 dom_catan(long double complex z)
302 {
303         return 1;
304 }
305
306 static int
307 dom_catanh(long double complex z)
308 {
309         return 1;
310 }
311
312 static int
313 dom_ccos(long double complex z)
314 {
315         return 1;
316 }
317
318 static int
319 dom_cexp(long double complex z)
320 {
321         return 1;
322 }
323
324 static int
325 dom_clog(long double complex z)
326 {
327         long_double_complex ldcz = { .z = z };
328
329         return (fpclassify(ldcz.parts[0]) != FP_ZERO ||
330                 fpclassify(ldcz.parts[1]) != FP_ZERO);
331 }
332
333 static int
334 dom_conj(long double complex z)
335 {
336         return 1;
337 }
338
339 static int
340 dom_cpow(long double complex z, long double complex w)
341 {
342         /* XXX */
343         return 1;
344 }
345
346 static int
347 dom_cproj(long double complex z)
348 {
349         return 1;
350 }
351
352 static int
353 dom_csin(long double complex z)
354 {
355         return 1;
356 }
357
358 static int
359 dom_csinh(long double complex z)
360 {
361         return 1;
362 }
363
364 static int
365 dom_csqrt(long double complex z)
366 {
367         return 1;
368 }
369
370 static int
371 dom_ctan(long double complex z)
372 {
373         /* XXX */
374         return 1;
375 }
376
377 /*******************************************************************************
378  *                      Basic arithmetic of complex numbers
379  ******************************************************************************/
380 static int
381 dom_cadd(long double complex z, long double complex w)
382 {
383         return 1;
384 }
385
386 static int
387 dom_csub(long double complex z, long double complex w)
388 {
389         return 1;
390 }
391 static int
392 dom_cmul(long double complex z, long double complex w)
393 {
394         return 1;
395 }
396 static int
397 dom_cdiv(long double complex z, long double complex w)
398 {
399         long_double_complex ldcw = { .z = w };
400
401         return (fpclassify(ldcw.parts[0]) != FP_ZERO ||
402                 fpclassify(ldcw.parts[1]) != FP_ZERO);
403 }
404 static int
405 dom_cneg(long double complex z)
406 {
407         return 1;
408 }
409
410 /*
411  * ISO/IEC 9899:1999 - 6.7.8.10 - Initialization
412  *
413  * If an object that has static storage duration is not initialized explicitly,
414  * then [...] if it has pointer type, it is initialized to a null pointer.
415  *
416  * Therefore, we can safely assume that f_namel, f_mpfr or f_mpc is NULL,
417  * if autoconf didn't define the corresponding HAVE_XYZ symbol for us.
418  */
419 static const struct fentry
420 ftable[] = {
421 /*******************************************************************************
422  *                              Real arithmetic
423  ******************************************************************************/
424         /* acos() */
425 #ifdef  HAVE_ACOS
426         {
427                 .f_narg = 1,
428                 .f_name = "acos",
429                 .f_libm_real = acos,
430 #ifdef  HAVE_ACOSL
431                 .f_namel = "acosl",
432                 .f_libml_real = acosl,
433 #endif
434                 .f_mpfr = mpfr_acos,
435                 .f_u.fp1 = dom_acos
436         },
437 #endif
438
439         /* acosh() */
440 #ifdef  HAVE_ACOSH
441         {
442                 .f_narg = 1,
443                 .f_name = "acosh",
444                 .f_libm_real = acosh,
445 #ifdef  HAVE_ACOSHL
446                 .f_namel = "acoshl",
447                 .f_libml_real = acoshl,
448 #endif
449                 .f_mpfr = mpfr_acosh,
450                 .f_u.fp1 = dom_acosh
451         },
452 #endif
453
454         /* asin() */
455 #ifdef  HAVE_ASIN
456         {
457                 .f_narg = 1,
458                 .f_name = "asin",
459                 .f_libm_real = asin,
460 #ifdef  HAVE_ASINL
461                 .f_namel = "asinl",
462                 .f_libml_real = asinl,
463 #endif
464                 .f_mpfr = mpfr_asin,
465                 .f_u.fp1 = dom_asin
466         },
467 #endif
468
469         /* asinh() */
470 #ifdef  HAVE_ASINH
471         {
472                 .f_narg = 1,
473                 .f_name = "asinh",
474                 .f_libm_real = asinh,
475 #ifdef  HAVE_ASINHL
476                 .f_namel = "asinhl",
477                 .f_libml_real = asinhl,
478 #endif
479                 .f_mpfr = mpfr_asinh,
480                 .f_u.fp1 = dom_asinh
481         },
482 #endif
483
484         /* atan() */
485 #ifdef  HAVE_ATAN
486         {
487                 .f_narg = 1,
488                 .f_name = "atan",
489                 .f_libm_real = atan,
490 #ifdef  HAVE_ATANL
491                 .f_namel = "atanl",
492                 .f_libml_real = atanl,
493 #endif
494                 .f_mpfr = mpfr_atan,
495                 .f_u.fp1 = dom_atan
496         },
497 #endif
498
499         /* atan2() */
500 #ifdef  HAVE_ATAN2
501         {
502                 .f_narg = 2,
503                 .f_name = "atan2",
504                 .f_libm_real = atan2,
505 #ifdef  HAVE_ATAN2L
506                 .f_namel = "atan2l",
507                 .f_libml_real = atan2l,
508 #endif
509                 .f_mpfr = mpfr_atan2,
510                 .f_u.fp2 = dom_atan2
511         },
512 #endif
513
514         /* atanh() */
515 #ifdef  HAVE_ATANH
516         {
517                 .f_narg = 1,
518                 .f_name = "atanh",
519                 .f_libm_real = atanh,
520 #ifdef  HAVE_ATANHL
521                 .f_namel = "atanhl",
522                 .f_libml_real = atanhl,
523 #endif
524                 .f_mpfr = mpfr_atanh,
525                 .f_u.fp1 = dom_atanh
526         },
527 #endif
528
529         /* cbrt() */
530 #ifdef  HAVE_CBRT
531         {
532                 .f_narg = 1,
533                 .f_name = "cbrt",
534                 .f_libm_real = cbrt,
535 #ifdef  HAVE_CBRTL
536                 .f_namel = "cbrtl",
537                 .f_libml_real = cbrtl,
538 #endif
539                 .f_mpfr = mpfr_cbrt,
540                 .f_u.fp1 = dom_cbrt
541         },
542 #endif
543
544         /* ceil() */
545 #ifdef  HAVE_CEIL
546         {
547                 .f_name = "ceil",
548                 .f_narg = 1,
549                 .f_libm_real = ceil,
550 #ifdef  HAVE_CEILL
551                 .f_namel = "ceill",
552                 .f_libml_real = ceill,
553 #endif
554                 .f_mpfr = mpfr_ceil,
555                 .f_u.fp1 = dom_ceil
556         },
557 #endif
558
559         /* cos() */
560 #ifdef  HAVE_COS
561         {
562                 .f_narg = 1,
563                 .f_name = "cos",
564                 .f_libm_real = cos,
565 #ifdef  HAVE_COSL
566                 .f_namel = "cosl",
567                 .f_libml_real = cosl,
568 #endif
569                 .f_mpfr = mpfr_cos,
570                 .f_u.fp1 = dom_cos
571         },
572 #endif
573
574         /* cosh() */
575 #ifdef  HAVE_COSH
576         {
577                 .f_narg = 1,
578                 .f_name = "cosh",
579                 .f_libm_real = cosh,
580 #ifdef  HAVE_COSHL
581                 .f_namel = "coshl",
582                 .f_libml_real = coshl,
583 #endif
584                 .f_mpfr = mpfr_cosh,
585                 .f_u.fp1 = dom_cosh
586         },
587 #endif
588
589         /* exp() */
590 #ifdef  HAVE_EXP
591         {
592                 .f_narg = 1,
593                 .f_name = "exp",
594                 .f_libm_real = exp,
595 #ifdef  HAVE_EXPL
596                 .f_namel = "expl",
597                 .f_libml_real = expl,
598 #endif
599                 .f_mpfr = mpfr_exp,
600                 .f_u.fp1 = dom_exp
601         },
602 #endif
603
604         /* expm1() */
605 #ifdef  HAVE_EXPM1
606         {
607                 .f_narg = 1,
608                 .f_name = "expm1",
609                 .f_libm_real = expm1,
610 #ifdef  HAVE_EXPM1L
611                 .f_namel = "expm1l",
612                 .f_libml_real = expm1l,
613 #endif
614                 .f_mpfr = mpfr_expm1,
615                 .f_u.fp1 = dom_expm1
616         },
617 #endif
618
619         /* exp2() */
620 #ifdef  HAVE_EXP2
621         {
622                 .f_narg = 1,
623                 .f_name = "exp2",
624                 .f_libm_real = exp2,
625 #ifdef  HAVE_EXP2L
626                 .f_namel = "exp2l",
627                 .f_libml_real = exp2l,
628 #endif
629                 .f_mpfr = mpfr_exp2,
630                 .f_u.fp1 = dom_exp2
631         },
632 #endif
633
634         /* erf() */
635 #ifdef  HAVE_ERF
636         {
637                 .f_narg = 1,
638                 .f_name = "erf",
639                 .f_libm_real = erf,
640 #ifdef  HAVE_ERFL
641                 .f_namel = "erfl",
642                 .f_libml_real = erfl,
643 #endif
644                 .f_mpfr = mpfr_erf,
645                 .f_u.fp1 = dom_erf
646         },
647 #endif
648
649         /* erfc() */
650 #ifdef  HAVE_ERFC
651         {
652                 .f_narg = 1,
653                 .f_name = "erfc",
654                 .f_libm_real = erfc,
655 #ifdef  HAVE_ERFCL
656                 .f_namel = "erfcl",
657                 .f_libml_real = erfcl,
658 #endif
659                 .f_mpfr = mpfr_erfc,
660                 .f_u.fp1 = dom_erfc
661         },
662 #endif
663
664         /* fabs() */
665 #ifdef  HAVE_FABS
666         {
667                 .f_narg = 1,
668                 .f_name = "fabs",
669                 .f_libm_real = fabs,
670 #ifdef  HAVE_FABSL
671                 .f_namel = "fabsl",
672                 .f_libml_real = fabsl,
673 #endif
674                 .f_mpfr = mpfr_abs,
675                 .f_u.fp1 = dom_fabs
676         },
677 #endif
678
679         /* floor() */
680 #ifdef  HAVE_FLOOR
681         {
682                 .f_narg = 1,
683                 .f_name = "floor",
684                 .f_libm_real = floor,
685 #ifdef  HAVE_FLOORL
686                 .f_namel = "floorl",
687                 .f_libml_real = floorl,
688 #endif
689                 .f_mpfr = mpfr_floor,
690                 .f_u.fp1 = dom_floor
691         },
692 #endif
693
694         /* fmod() */
695 #ifdef  HAVE_FMOD
696         {
697                 .f_narg = 2,
698                 .f_name = "fmod",
699                 .f_libm_real = fmod,
700 #ifdef  HAVE_FMODL
701                 .f_namel = "fmodl",
702                 .f_libml_real = fmodl,
703 #endif
704                 .f_mpfr = mpfr_fmod,
705                 .f_u.fp1 = dom_fmod
706         },
707 #endif
708
709         /* hypot() */
710 #ifdef  HAVE_HYPOT
711         {
712                 .f_narg = 2,
713                 .f_name = "hypot",
714                 .f_libm_real = hypot,
715 #ifdef  HAVE_HYPOTL
716                 .f_namel = "hypotl",
717                 .f_libml_real = hypotl,
718 #endif
719                 .f_mpfr = mpfr_hypot,
720                 .f_u.fp2 = dom_hypot
721         },
722 #endif
723
724         /* j0() */
725 #ifdef  HAVE_J0
726         {
727                 .f_narg = 1,
728                 .f_name = "j0",
729                 .f_libm_real = j0,
730 #ifdef  HAVE_J0Lxxx
731                 .f_namel = "j0l",
732                 .f_libml_real = j0l,
733 #endif
734                 .f_mpfr = mpfr_j0,
735                 .f_u.fp2 = dom_j0
736         },
737 #endif
738
739         /* j1() */
740 #ifdef  HAVE_J1
741         {
742                 .f_narg = 1,
743                 .f_name = "j1",
744                 .f_libm_real = j1,
745 #ifdef  HAVE_J1Lxxx
746                 .f_namel = "j1l",
747                 .f_libml_real = j1l,
748 #endif
749                 .f_mpfr = mpfr_j1,
750                 .f_u.fp2 = dom_j1
751         },
752 #endif
753
754
755         /* log()*/
756 #ifdef  HAVE_LOG
757         {
758                 .f_narg = 1,
759                 .f_name = "log",
760                 .f_libm_real = log,
761 #ifdef  HAVE_LOGL
762                 .f_namel = "logl",
763                 .f_libml_real = logl,
764 #endif
765                 .f_mpfr = mpfr_log,
766                 .f_u.fp1 = dom_log
767         },
768 #endif
769
770         /* log1p() */
771 #ifdef  HAVE_LOG1P
772         {
773                 .f_narg = 1,
774                 .f_name = "log1p",
775                 .f_libm_real = log1p,
776 #ifdef  HAVE_LOG1PL
777                 .f_namel = "log1pl",
778                 .f_libml_real = log1pl,
779 #endif
780                 .f_mpfr = mpfr_log1p,
781                 .f_u.fp1 = dom_log1p
782         },
783 #endif
784
785         /* log10() */
786 #ifdef  HAVE_LOG10
787         {
788                 .f_narg = 1,
789                 .f_name = "log10",
790                 .f_libm_real = log10,
791 #ifdef  HAVE_LOG10L
792                 .f_namel = "log10l",
793                 .f_libml_real = log10l,
794 #endif
795                 .f_mpfr = mpfr_log10,
796                 .f_u.fp1 = dom_log10
797         },
798 #endif
799
800         /* log2() */
801 #ifdef  HAVE_LOG2
802         {
803                 .f_narg = 1,
804                 .f_name = "log2",
805                 .f_libm_real = log2,
806 #ifdef  HAVE_LOG2L
807                 .f_namel = "log2l",
808                 .f_libml_real = log2l,
809 #endif
810                 .f_mpfr = mpfr_log2,
811                 .f_u.fp1 = dom_log2
812         },
813 #endif
814
815         /* remainder() */
816 #ifdef  HAVE_REMAINDER
817         {
818                 .f_narg = 2,
819                 .f_name = "remainder",
820                 .f_libm_real = remainder,
821 #ifdef  HAVE_REMAINDERL
822                 .f_namel = "remainderl",
823                 .f_libml_real = remainderl,
824 #endif
825                 .f_mpfr = mpfr_remainder,
826                 .f_u.fp2 = dom_remainder
827         },
828 #endif
829
830         /* rint() */
831 #ifdef  HAVE_RINT
832         {
833                 .f_narg = 1,
834                 .f_name = "rint",
835                 .f_libm_real = rint,
836 #ifdef  HAVE_RINTL
837                 .f_namel = "rintl",
838                 .f_libml_real = rintl,
839 #endif
840                 .f_mpfr = mpfr_rint,
841                 .f_u.fp1 = dom_rint
842         },
843 #endif
844
845         /* round() */
846 #ifdef  HAVE_ROUND
847         {
848                 .f_narg = 1,
849                 .f_name = "round",
850                 .f_libm_real = round,
851 #ifdef  HAVE_ROUNDL
852                 .f_namel = "roundl",
853                 .f_libml_real = roundl,
854 #endif
855                 .f_mpfr = mpfr_round,
856                 .f_u.fp1 = dom_round
857         },
858 #endif
859
860         /* sin() */
861 #ifdef  HAVE_SIN
862         {
863                 .f_narg = 1,
864                 .f_name = "sin",
865                 .f_libm_real = sin,
866 #ifdef  HAVE_SINL
867                 .f_namel = "sinl",
868                 .f_libml_real = sinl,
869 #endif
870                 .f_mpfr = mpfr_sin,
871                 .f_u.fp1 = dom_sin
872         },
873 #endif
874
875         /* sinh() */
876 #ifdef  HAVE_SINH
877         {
878                 .f_narg = 1,
879                 .f_name = "sinh",
880                 .f_libm_real = sinh,
881 #ifdef  HAVE_SINHL
882                 .f_namel = "sinhl",
883                 .f_libml_real = sinhl,
884 #endif
885                 .f_mpfr = mpfr_sinh,
886                 .f_u.fp1 = dom_sinh
887         },
888 #endif
889
890         /* sqrt() */
891 #ifdef  HAVE_SQRT
892         {
893                 .f_narg = 1,
894                 .f_name = "sqrt",
895                 .f_libm_real = sqrt,
896 #ifdef  HAVE_SQRTL
897                 .f_namel = "sqrtl",
898                 .f_libml_real = sqrtl,
899 #endif
900                 .f_mpfr = mpfr_sqrt,
901                 .f_u.fp1 = dom_sqrt
902         },
903 #endif
904
905         /* pow() */
906 #ifdef  HAVE_POW
907         {
908                 .f_narg = 2,
909                 .f_name = "pow",
910                 .f_libm_real = pow,
911 #ifdef  HAVE_POWL
912                 .f_namel = "powl",
913                 .f_libml_real = powl,
914 #endif
915                 .f_mpfr = mpfr_pow,
916                 .f_u.fp2 = dom_pow
917         },
918 #endif
919
920         /* tan() */
921 #ifdef  HAVE_TAN
922         {
923                 .f_narg = 1,
924                 .f_name = "tan",
925                 .f_libm_real = tan,
926 #ifdef  HAVE_TANL
927                 .f_namel = "tanl",
928                 .f_libml_real = tanl,
929 #endif
930                 .f_mpfr = mpfr_tan,
931                 .f_u.fp1 = dom_tan
932         },
933 #endif
934
935         /* tanh() */
936 #ifdef  HAVE_TANH
937         {
938                 .f_narg = 1,
939                 .f_name = "tanh",
940                 .f_libm_real = tanh,
941 #ifdef  HAVE_TANHL
942                 .f_namel = "tanhl",
943                 .f_libml_real = tanhl,
944 #endif
945                 .f_mpfr = mpfr_tanh,
946                 .f_u.fp1 = dom_tanh
947         },
948 #endif
949
950         /* tgamma() */
951 #ifdef  HAVE_TGAMMA
952         {
953                 .f_narg = 1,
954                 .f_name = "tgamma",
955                 .f_libm_real = tgamma,
956 #ifdef  HAVE_TGAMMAL
957                 .f_namel = "tgammal",
958                 .f_libml_real = tgammal,
959 #endif
960                 .f_mpfr = mpfr_gamma,
961                 .f_u.fp1 = dom_tgamma
962         },
963 #endif
964
965         /* trunc() */
966 #ifdef  HAVE_TRUNC
967         {
968                 .f_narg = 1,
969                 .f_name = "trunc",
970                 .f_libm_real = trunc,
971 #ifdef  HAVE_TGAMMAL
972                 .f_namel = "truncl",
973                 .f_libml_real = truncl,
974 #endif
975                 .f_mpfr = mpfr_trunc,
976                 .f_u.fp1 = dom_trunc
977         },
978 #endif
979
980         /* y0() */
981 #ifdef  HAVE_Y0
982         {
983                 .f_narg = 1,
984                 .f_name = "y0",
985                 .f_libm_real = y0,
986                 .f_mpfr = mpfr_y0,
987                 .f_u.fp1 = dom_y0
988         },
989 #endif
990
991         /* y1() */
992 #ifdef  HAVE_Y1
993         {
994                 .f_narg = 1,
995                 .f_name = "y1",
996                 .f_libm_real = y1,
997                 .f_mpfr = mpfr_y1,
998                 .f_u.fp1 = dom_y1
999         },
1000 #endif
1001
1002         /* yn() */
1003 #ifdef  HAVE_YNxxx
1004         {
1005                 .f_narg = 2,
1006                 .f_name = "yn",
1007                 .f_libm_real = yn,
1008                 .f_mpfr = mpfr_yn,
1009                 .f_u.fp2 = dom_yn
1010         },
1011 #endif
1012
1013 /*******************************************************************************
1014  *                              Complex arithmetic
1015  ******************************************************************************/
1016         /* cabs() */
1017 #ifdef  HAVE_CABS
1018         {
1019                 .f_narg = 1,
1020                 .f_name = "cabs",
1021                 .f_libm_complex = cabs,
1022 #ifdef  HAVE_CABSL
1023                 .f_namel = "cabsl",
1024                 .f_libml_complex = cabsl,
1025 #endif
1026                 .f_mpc = mpc_abs,
1027                 .f_uc.fp1 = dom_cabs
1028         },
1029 #endif
1030
1031         /* cacos() */
1032 #ifdef  HAVE_CACOS
1033         {
1034                 .f_narg = 1,
1035                 .f_name = "cacos",
1036                 .f_libm_complex = cacos,
1037 #ifdef  HAVE_CACOSL
1038                 .f_namel = "cacosl",
1039                 .f_libml_complex = cacosl,
1040 #endif
1041                 .f_mpc = mpc_acos,
1042                 .f_uc.fp1 = dom_cacos
1043         },
1044 #endif
1045
1046         /* cacosh() */
1047 #ifdef  HAVE_CACOSH
1048         {
1049                 .f_narg = 1,
1050                 .f_name = "cacosh",
1051                 .f_libm_complex = cacosh,
1052 #ifdef  HAVE_CACOSHL
1053                 .f_namel = "cacoshl",
1054                 .f_libml_complex = cacoshl,
1055 #endif
1056                 .f_mpc = mpc_acosh,
1057                 .f_uc.fp1 = dom_cacosh
1058         },
1059 #endif
1060
1061         /* carg() */
1062 #ifdef  HAVE_CARG
1063         {
1064                 .f_narg = 1,
1065                 .f_name = "carg",
1066                 .f_libm_complex = carg,
1067 #ifdef  HAVE_CARGL
1068                 .f_namel = "cargl",
1069                 .f_libml_complex = cargl,
1070 #endif
1071                 .f_mpc = mpc_arg,
1072                 .f_uc.fp1 = dom_carg
1073         },
1074 #endif
1075
1076         /* casin() */
1077 #ifdef  HAVE_CASIN
1078         {
1079                 .f_narg = 1,
1080                 .f_name = "casin",
1081                 .f_libm_complex = casin,
1082 #ifdef  HAVE_CASINL
1083                 .f_namel = "casinl",
1084                 .f_libml_complex = casinl,
1085 #endif
1086                 .f_mpc = mpc_asin,
1087                 .f_uc.fp1 = dom_casin
1088         },
1089 #endif
1090
1091         /* casinh() */
1092 #ifdef  HAVE_CASINH
1093         {
1094                 .f_narg = 1,
1095                 .f_name = "casinh",
1096                 .f_libm_complex = casinh,
1097 #ifdef  HAVE_CASINHL
1098                 .f_namel = "casinhl",
1099                 .f_libml_complex = casinhl,
1100 #endif
1101                 .f_mpc = mpc_asinh,
1102                 .f_uc.fp1 = dom_casinh
1103         },
1104 #endif
1105
1106         /* catan() */
1107 #ifdef  HAVE_CATAN
1108         {
1109                 .f_narg = 1,
1110                 .f_name = "catan",
1111                 .f_libm_complex = catan,
1112 #ifdef  HAVE_CATANL
1113                 .f_namel = "catanl",
1114                 .f_libml_complex = catanl,
1115 #endif
1116                 .f_mpc = mpc_atan,
1117                 .f_uc.fp1 = dom_catan
1118         },
1119 #endif
1120
1121         /* catanh() */
1122 #ifdef  HAVE_CATANH
1123         {
1124                 .f_narg = 1,
1125                 .f_name = "catanh",
1126                 .f_libm_complex = catanh,
1127 #ifdef  HAVE_CATANHL
1128                 .f_namel = "catanhl",
1129                 .f_libml_complex = catanhl,
1130 #endif
1131                 .f_mpc = mpc_atanh,
1132                 .f_uc.fp1 = dom_catanh
1133         },
1134 #endif
1135
1136         /* ccos() */
1137 #ifdef  HAVE_CCOS
1138         {
1139                 .f_narg = 1,
1140                 .f_name = "ccos",
1141                 .f_libm_complex = ccos,
1142 #ifdef  HAVE_CCOSL
1143                 .f_namel = "ccosl",
1144                 .f_libml_complex = ccosl,
1145 #endif
1146                 .f_mpc = mpc_cos,
1147                 .f_uc.fp1 = dom_ccos
1148         },
1149 #endif
1150
1151         /* cexp() */
1152 #ifdef  HAVE_CEXP
1153         {
1154                 .f_narg = 1,
1155                 .f_name = "cexp",
1156                 .f_libm_complex = cexp,
1157 #ifdef  HAVE_CEXPL
1158                 .f_namel = "cexpl",
1159                 .f_libml_complex = cexpl,
1160 #endif
1161                 .f_mpc = mpc_exp,
1162                 .f_uc.fp1 = dom_cexp
1163         },
1164 #endif
1165
1166         /* clog() */
1167 #ifdef  HAVE_CLOG
1168         {
1169                 .f_narg = 1,
1170                 .f_name = "clog",
1171                 .f_libm_complex = clog,
1172 #ifdef  HAVE_CLOGL
1173                 .f_namel = "clogl",
1174                 .f_libml_complex = clogl,
1175 #endif
1176                 .f_mpc = mpc_log,
1177                 .f_uc.fp1 = dom_clog
1178         },
1179 #endif
1180
1181         /* conj() */
1182 #ifdef  HAVE_CONJ
1183         {
1184                 .f_narg = 1,
1185                 .f_name = "conj",
1186                 .f_libm_complex = conj,
1187 #ifdef  HAVE_CONJL
1188                 .f_namel = "conjl",
1189                 .f_libml_complex = conjl,
1190 #endif
1191                 .f_mpc = mpc_conj,
1192                 .f_uc.fp1 = dom_conj
1193         },
1194 #endif
1195
1196         /* cpow() */
1197 #ifdef  HAVE_CPOW
1198         {
1199                 .f_narg = 2,
1200                 .f_name = "cpow",
1201                 .f_libm_complex = cpow,
1202 #ifdef  HAVE_CPOWL
1203                 .f_namel = "cpowl",
1204                 .f_libml_complex = cpowl,
1205 #endif
1206                 .f_mpc = mpc_pow,
1207                 .f_uc.fp1 = dom_cpow
1208         },
1209 #endif
1210
1211         /* cproj() */
1212 #ifdef  HAVE_CPROJ
1213         {
1214                 .f_narg = 1,
1215                 .f_name = "cproj",
1216                 .f_libm_complex = cproj,
1217 #ifdef  HAVE_CPROJL
1218                 .f_namel = "cprojl",
1219                 .f_libml_complex = cprojl,
1220 #endif
1221                 .f_mpc = mpc_proj,
1222                 .f_uc.fp1 = dom_cproj
1223         },
1224 #endif
1225
1226         /* csin() */
1227 #ifdef  HAVE_CSIN
1228         {
1229                 .f_narg = 1,
1230                 .f_name = "csin",
1231                 .f_libm_complex = csin,
1232 #ifdef  HAVE_CSINL
1233                 .f_namel = "csinl",
1234                 .f_libml_complex = csinl,
1235 #endif
1236                 .f_mpc = mpc_sin,
1237                 .f_uc.fp1 = dom_csin
1238         },
1239 #endif
1240
1241         /* csinh() */
1242 #ifdef  HAVE_CSINH
1243         {
1244                 .f_narg = 1,
1245                 .f_name = "csinh",
1246                 .f_libm_complex = csinh,
1247 #ifdef  HAVE_CSINHL
1248                 .f_namel = "csinhl",
1249                 .f_libml_complex = csinhl,
1250 #endif
1251                 .f_mpc = mpc_sinh,
1252                 .f_uc.fp1 = dom_csinh
1253         },
1254 #endif
1255
1256         /* csqrt() */
1257 #ifdef  HAVE_CSQRT
1258         {
1259                 .f_narg = 1,
1260                 .f_name = "csqrt",
1261                 .f_libm_complex = csqrt,
1262 #ifdef  HAVE_CSQRTL
1263                 .f_namel = "csqrtl",
1264                 .f_libml_complex = csqrtl,
1265 #endif
1266                 .f_mpc = mpc_sqrt,
1267                 .f_uc.fp1 = dom_csqrt
1268         },
1269 #endif
1270
1271         /* ctan() */
1272 #ifdef  HAVE_CTAN
1273         {
1274                 .f_narg = 1,
1275                 .f_name = "ctan",
1276                 .f_libm_complex = ctan,
1277 #ifdef  HAVE_CTANL
1278                 .f_namel = "ctanl",
1279                 .f_libml_complex = ctanl,
1280 #endif
1281                 .f_mpc = mpc_tan,
1282                 .f_uc.fp1 = dom_ctan
1283         },
1284 #endif
1285
1286 /*******************************************************************************
1287  *                      Basic arithmetic of complex numbers
1288  ******************************************************************************/
1289         /* cadd() */
1290         {
1291                 .f_narg = 2,
1292                 .f_name = "cadd",
1293                 .f_libm_complex = cadd,
1294                 .f_namel = "caddl",
1295                 .f_libml_complex = caddl,
1296                 .f_mpc = mpc_add,
1297                 .f_uc.fp2 = dom_cadd
1298         },
1299
1300         /* csub() */
1301         {
1302                 .f_narg = 2,
1303                 .f_name = "csub",
1304                 .f_libm_complex = csub,
1305                 .f_namel = "csubl",
1306                 .f_libml_complex = csubl,
1307                 .f_mpc = mpc_sub,
1308                 .f_uc.fp2 = dom_csub
1309         },
1310
1311         /* cmul() */
1312         {
1313                 .f_narg = 2,
1314                 .f_name = "cmul",
1315                 .f_libm_complex = cmul,
1316                 .f_namel = "cmull",
1317                 .f_libml_complex = cmull,
1318                 .f_mpc = mpc_mul,
1319                 .f_uc.fp2 = dom_cmul
1320         },
1321
1322         /* cdiv() */
1323         {
1324                 .f_narg = 2,
1325                 .f_name = "cdiv",
1326                 .f_libm_complex = cdiv,
1327                 .f_namel = "cdivl",
1328                 .f_libml_complex = cdivl,
1329                 .f_mpc = mpc_div,
1330                 .f_uc.fp2 = dom_cdiv
1331         },
1332
1333         /* cneg() */
1334         {
1335                 .f_narg = 1,
1336                 .f_name = "cneg",
1337                 .f_libm_complex = cneg,
1338                 .f_namel = "cnegl",
1339                 .f_libml_complex = cnegl,
1340                 .f_mpc = mpc_neg,
1341                 .f_uc.fp2 = dom_cneg
1342         }
1343 };
1344
1345 const int fsize = sizeof(ftable) / sizeof(ftable[0]);
1346
1347 static void
1348 assertfunction(const struct fentry *f)
1349 {
1350         assert(f);
1351         assert(f->f_narg == 1 || f->f_narg == 2);
1352         assert(f->f_name);
1353
1354         if (f->f_mpfr) {
1355                 assert(f->f_u.fp1 || f->f_u.fp2);
1356                 assert(f->f_libm_real);
1357                 if (f->f_namel)
1358                         assert(f->f_libml_real);
1359         }
1360
1361         if (f->f_mpc) {
1362                 assert(f->f_uc.fp1 || f->f_u.fp2);
1363                 assert(f->f_libm_complex);
1364                 if (f->f_namel)
1365                         assert(f->f_libml_complex);
1366         }
1367
1368         assert(f->f_mpfr || f->f_mpc);
1369 }
1370
1371 const struct fentry *
1372 getfunctionbyidx(int idx)
1373 {
1374         assert(0 <= idx && idx < fsize);
1375
1376         return (&ftable[idx]);
1377 }
1378
1379 const struct fentry *
1380 getfunctionbyname(const char *fname)
1381 {
1382         const struct fentry *f;
1383         int i;
1384
1385         assert(fname);
1386
1387         for (i = 0; i < fsize; i++) {
1388                 f = &ftable[i];
1389                 if ((strcmp(fname, f->f_name ) == 0) ||
1390                     (f->f_namel && strcmp(fname, f->f_namel) == 0)) {
1391                         assertfunction(f);
1392                         return (f);
1393                 }
1394         }
1395
1396         return (NULL);
1397 }
1398
1399 void
1400 printfunctions(void)
1401 {
1402         const struct fentry *f;
1403         int i, cnt;
1404
1405         for (i = 0, cnt = 0; i < fsize; i++, cnt++) {
1406                 f = &ftable[i];
1407                 printf("%-10s ", f->f_name);
1408                 if (cnt % 5 == 4)
1409                         printf("\n");
1410                 if (f->f_namel) {
1411                         cnt++;
1412                         printf("%-10s ", f->f_namel);
1413                         if (cnt % 5 == 4)
1414                                 printf("\n");
1415                 }
1416         }
1417
1418         /* If cnt % 5 was equal to 4, then now it's equal to 0 */
1419         if (cnt % 5 != 0)
1420                 printf("\n");
1421 }