1*90a8ff21Smrg /* mpcheck-float -- compare mpc functions against "float complex"
2*90a8ff21Smrg from the GNU libc implementation
3*90a8ff21Smrg
4*90a8ff21Smrg Copyright (C) 2020 INRIA
5*90a8ff21Smrg
6*90a8ff21Smrg This file is part of GNU MPC.
7*90a8ff21Smrg
8*90a8ff21Smrg GNU MPC is free software; you can redistribute it and/or modify it under
9*90a8ff21Smrg the terms of the GNU Lesser General Public License as published by the
10*90a8ff21Smrg Free Software Foundation; either version 3 of the License, or (at your
11*90a8ff21Smrg option) any later version.
12*90a8ff21Smrg
13*90a8ff21Smrg GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
14*90a8ff21Smrg WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15*90a8ff21Smrg FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
16*90a8ff21Smrg more details.
17*90a8ff21Smrg
18*90a8ff21Smrg You should have received a copy of the GNU Lesser General Public License
19*90a8ff21Smrg along with this program. If not, see http://www.gnu.org/licenses/ .
20*90a8ff21Smrg */
21*90a8ff21Smrg
22*90a8ff21Smrg /* the GNU libc provides the following functions (as of 2.31),
23*90a8ff21Smrg with 'f' suffix for the float/binary32 version, with no suffix
24*90a8ff21Smrg for the double/binary64 version, with 'l' suffix for the long double
25*90a8ff21Smrg version, and with 'f128' suffix for the __float128 version:
26*90a8ff21Smrg
27*90a8ff21Smrg cabs casinh cexp csinh
28*90a8ff21Smrg cacos catan clog csqrt
29*90a8ff21Smrg cacosh catanh clog10 ctan
30*90a8ff21Smrg carg ccos cpow ctanh
31*90a8ff21Smrg casin ccosh csin
32*90a8ff21Smrg */
33*90a8ff21Smrg
34*90a8ff21Smrg #define _GNU_SOURCE /* for clog10 */
35*90a8ff21Smrg #include <stdio.h>
36*90a8ff21Smrg #include <stdlib.h>
37*90a8ff21Smrg #include <string.h>
38*90a8ff21Smrg #include <complex.h>
39*90a8ff21Smrg #include <sys/types.h>
40*90a8ff21Smrg #include <unistd.h>
41*90a8ff21Smrg #include <assert.h>
42*90a8ff21Smrg #include "mpc.h"
43*90a8ff21Smrg #ifdef __GNUC__
44*90a8ff21Smrg #include <gnu/libc-version.h>
45*90a8ff21Smrg #endif
46*90a8ff21Smrg
47*90a8ff21Smrg #define PRECISION 24
48*90a8ff21Smrg #define EMAX 128
49*90a8ff21Smrg #define TYPE float
50*90a8ff21Smrg #define SUFFIX f
51*90a8ff21Smrg
52*90a8ff21Smrg #define mpfr_set_type mpfr_set_flt
53*90a8ff21Smrg
54*90a8ff21Smrg static TYPE complex
mpc_get_type(mpc_t x,mpc_rnd_t rnd)55*90a8ff21Smrg mpc_get_type (mpc_t x, mpc_rnd_t rnd)
56*90a8ff21Smrg {
57*90a8ff21Smrg /* there is no mpc_get_fltc function */
58*90a8ff21Smrg return (TYPE complex) mpc_get_dc (x, rnd);
59*90a8ff21Smrg }
60*90a8ff21Smrg
61*90a8ff21Smrg static int
mpc_set_type(mpc_t x,TYPE complex y,mpc_rnd_t rnd)62*90a8ff21Smrg mpc_set_type (mpc_t x, TYPE complex y, mpc_rnd_t rnd)
63*90a8ff21Smrg {
64*90a8ff21Smrg /* there is no mpc_set_fltc function */
65*90a8ff21Smrg return mpc_set_dc (x, (double complex) y, rnd);
66*90a8ff21Smrg }
67*90a8ff21Smrg
68*90a8ff21Smrg gmp_randstate_t state;
69*90a8ff21Smrg mpz_t expz; /* global variable used in mpcheck_random */
70*90a8ff21Smrg unsigned long seed = 0;
71*90a8ff21Smrg int verbose = 0;
72*90a8ff21Smrg mpfr_exp_t emin, emax;
73*90a8ff21Smrg
74*90a8ff21Smrg #include "mpcheck-common.c"
75*90a8ff21Smrg
76*90a8ff21Smrg #define FOO add
77*90a8ff21Smrg #define CFOO(x,y) (x+y)
78*90a8ff21Smrg #include "mpcheck-template3.c"
79*90a8ff21Smrg
80*90a8ff21Smrg #define FOO sub
81*90a8ff21Smrg #define CFOO(x,y) (x-y)
82*90a8ff21Smrg #include "mpcheck-template3.c"
83*90a8ff21Smrg
84*90a8ff21Smrg #define FOO mul
85*90a8ff21Smrg #define CFOO(x,y) (x*y)
86*90a8ff21Smrg #include "mpcheck-template3.c"
87*90a8ff21Smrg
88*90a8ff21Smrg #define FOO div
89*90a8ff21Smrg #define CFOO(x,y) (x/y)
90*90a8ff21Smrg #include "mpcheck-template3.c"
91*90a8ff21Smrg
92*90a8ff21Smrg #define FOO pow
93*90a8ff21Smrg #include "mpcheck-template3.c"
94*90a8ff21Smrg
95*90a8ff21Smrg #define FOO abs
96*90a8ff21Smrg #include "mpcheck-template2.c"
97*90a8ff21Smrg
98*90a8ff21Smrg #define FOO arg
99*90a8ff21Smrg #include "mpcheck-template2.c"
100*90a8ff21Smrg
101*90a8ff21Smrg #define FOO sqrt
102*90a8ff21Smrg #include "mpcheck-template1.c"
103*90a8ff21Smrg
104*90a8ff21Smrg #define FOO acos
105*90a8ff21Smrg #include "mpcheck-template1.c"
106*90a8ff21Smrg
107*90a8ff21Smrg #define FOO acosh
108*90a8ff21Smrg #include "mpcheck-template1.c"
109*90a8ff21Smrg
110*90a8ff21Smrg #define FOO asin
111*90a8ff21Smrg #include "mpcheck-template1.c"
112*90a8ff21Smrg
113*90a8ff21Smrg #define FOO asinh
114*90a8ff21Smrg #include "mpcheck-template1.c"
115*90a8ff21Smrg
116*90a8ff21Smrg #define FOO atan
117*90a8ff21Smrg #include "mpcheck-template1.c"
118*90a8ff21Smrg
119*90a8ff21Smrg #define FOO atanh
120*90a8ff21Smrg #include "mpcheck-template1.c"
121*90a8ff21Smrg
122*90a8ff21Smrg #define FOO cos
123*90a8ff21Smrg #include "mpcheck-template1.c"
124*90a8ff21Smrg
125*90a8ff21Smrg #define FOO cosh
126*90a8ff21Smrg #include "mpcheck-template1.c"
127*90a8ff21Smrg
128*90a8ff21Smrg #define FOO exp
129*90a8ff21Smrg #include "mpcheck-template1.c"
130*90a8ff21Smrg
131*90a8ff21Smrg #define FOO log
132*90a8ff21Smrg #include "mpcheck-template1.c"
133*90a8ff21Smrg
134*90a8ff21Smrg #define FOO log10
135*90a8ff21Smrg #include "mpcheck-template1.c"
136*90a8ff21Smrg
137*90a8ff21Smrg #define FOO sin
138*90a8ff21Smrg #include "mpcheck-template1.c"
139*90a8ff21Smrg
140*90a8ff21Smrg #define FOO sinh
141*90a8ff21Smrg #include "mpcheck-template1.c"
142*90a8ff21Smrg
143*90a8ff21Smrg #define FOO tan
144*90a8ff21Smrg #include "mpcheck-template1.c"
145*90a8ff21Smrg
146*90a8ff21Smrg #define FOO tanh
147*90a8ff21Smrg #include "mpcheck-template1.c"
148*90a8ff21Smrg
149*90a8ff21Smrg int
main(int argc,char * argv[])150*90a8ff21Smrg main (int argc, char *argv[])
151*90a8ff21Smrg {
152*90a8ff21Smrg mpfr_prec_t p = PRECISION; /* precision of 'float' */
153*90a8ff21Smrg unsigned long n = 1000000; /* default number of random tests per function */
154*90a8ff21Smrg
155*90a8ff21Smrg while (argc >= 2 && argv[1][0] == '-')
156*90a8ff21Smrg {
157*90a8ff21Smrg if (argc >= 3 && strcmp (argv[1], "-p") == 0)
158*90a8ff21Smrg {
159*90a8ff21Smrg p = atoi (argv[2]);
160*90a8ff21Smrg argc -= 2;
161*90a8ff21Smrg argv += 2;
162*90a8ff21Smrg }
163*90a8ff21Smrg else if (argc >= 3 && strcmp (argv[1], "-seed") == 0)
164*90a8ff21Smrg {
165*90a8ff21Smrg seed = atoi (argv[2]);
166*90a8ff21Smrg argc -= 2;
167*90a8ff21Smrg argv += 2;
168*90a8ff21Smrg }
169*90a8ff21Smrg else if (argc >= 3 && strcmp (argv[1], "-num") == 0)
170*90a8ff21Smrg {
171*90a8ff21Smrg n = atoi (argv[2]);
172*90a8ff21Smrg argc -= 2;
173*90a8ff21Smrg argv += 2;
174*90a8ff21Smrg }
175*90a8ff21Smrg else if (strcmp (argv[1], "-v") == 0)
176*90a8ff21Smrg {
177*90a8ff21Smrg verbose ++;
178*90a8ff21Smrg argc --;
179*90a8ff21Smrg argv ++;
180*90a8ff21Smrg }
181*90a8ff21Smrg else if (strcmp (argv[1], "-check") == 0)
182*90a8ff21Smrg {
183*90a8ff21Smrg recheck = 1;
184*90a8ff21Smrg argc --;
185*90a8ff21Smrg argv ++;
186*90a8ff21Smrg }
187*90a8ff21Smrg else
188*90a8ff21Smrg {
189*90a8ff21Smrg fprintf (stderr, "Unknown option %s\n", argv[1]);
190*90a8ff21Smrg exit (1);
191*90a8ff21Smrg }
192*90a8ff21Smrg }
193*90a8ff21Smrg
194*90a8ff21Smrg /* set exponent range */
195*90a8ff21Smrg emin = -EMAX - PRECISION + 4; /* should be -148 */
196*90a8ff21Smrg emax = EMAX;
197*90a8ff21Smrg mpfr_set_emin (emin);
198*90a8ff21Smrg mpfr_set_emax (emax);
199*90a8ff21Smrg
200*90a8ff21Smrg gmp_randinit_default (state);
201*90a8ff21Smrg mpz_init (expz);
202*90a8ff21Smrg
203*90a8ff21Smrg printf ("Using GMP %s, MPFR %s\n", gmp_version, mpfr_get_version ());
204*90a8ff21Smrg
205*90a8ff21Smrg #ifdef __GNUC__
206*90a8ff21Smrg printf ("GNU libc version: %s\n", gnu_get_libc_version ());
207*90a8ff21Smrg printf ("GNU libc release: %s\n", gnu_get_libc_release ());
208*90a8ff21Smrg #endif
209*90a8ff21Smrg
210*90a8ff21Smrg if (seed == 0)
211*90a8ff21Smrg seed = getpid ();
212*90a8ff21Smrg printf ("Using random seed %lu\n", seed);
213*90a8ff21Smrg
214*90a8ff21Smrg /* (complex,complex) -> complex */
215*90a8ff21Smrg test_add (p, n);
216*90a8ff21Smrg test_sub (p, n);
217*90a8ff21Smrg test_mul (p, n);
218*90a8ff21Smrg test_div (p, n);
219*90a8ff21Smrg test_pow (p, n);
220*90a8ff21Smrg
221*90a8ff21Smrg /* complex -> real */
222*90a8ff21Smrg test_abs (p, n);
223*90a8ff21Smrg test_arg (p, n);
224*90a8ff21Smrg
225*90a8ff21Smrg /* complex -> complex */
226*90a8ff21Smrg test_sqrt (p, n);
227*90a8ff21Smrg test_acos (p, n);
228*90a8ff21Smrg test_acosh (p, n);
229*90a8ff21Smrg test_asin (p, n);
230*90a8ff21Smrg test_asinh (p, n);
231*90a8ff21Smrg test_atan (p, n);
232*90a8ff21Smrg test_atanh (p, n);
233*90a8ff21Smrg test_cos (p, n);
234*90a8ff21Smrg test_cosh (p, n);
235*90a8ff21Smrg test_exp (p, n);
236*90a8ff21Smrg test_log (p, n);
237*90a8ff21Smrg test_log10 (p, n);
238*90a8ff21Smrg test_sin (p, n);
239*90a8ff21Smrg test_sinh (p, n);
240*90a8ff21Smrg test_tan (p, n);
241*90a8ff21Smrg test_tanh (p, n);
242*90a8ff21Smrg
243*90a8ff21Smrg gmp_randclear (state);
244*90a8ff21Smrg mpz_clear (expz);
245*90a8ff21Smrg
246*90a8ff21Smrg report_maximal_errors ();
247*90a8ff21Smrg
248*90a8ff21Smrg return 0;
249*90a8ff21Smrg }
250