1*90a8ff21Smrg /* mpcheck-float128 -- compare mpc functions against "__float128 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 #define MPFR_WANT_FLOAT128
43*90a8ff21Smrg #include "mpc.h"
44*90a8ff21Smrg #ifdef __GNUC__
45*90a8ff21Smrg #include <gnu/libc-version.h>
46*90a8ff21Smrg #endif
47*90a8ff21Smrg
48*90a8ff21Smrg #define PRECISION 113
49*90a8ff21Smrg #define EMAX 16384
50*90a8ff21Smrg #define TYPE _Float128
51*90a8ff21Smrg #define SUFFIX f128
52*90a8ff21Smrg
53*90a8ff21Smrg #define mpfr_set_type mpfr_set_float128
54*90a8ff21Smrg
55*90a8ff21Smrg static TYPE complex
mpc_get_type(mpc_t z,mpc_rnd_t rnd)56*90a8ff21Smrg mpc_get_type (mpc_t z, mpc_rnd_t rnd)
57*90a8ff21Smrg {
58*90a8ff21Smrg TYPE x, y;
59*90a8ff21Smrg /* there is no mpc_get_float128c function */
60*90a8ff21Smrg x = mpfr_get_float128 (mpc_realref (z), MPC_RND_RE(rnd));
61*90a8ff21Smrg y = mpfr_get_float128 (mpc_imagref (z), MPC_RND_IM(rnd));
62*90a8ff21Smrg return x + I * y;
63*90a8ff21Smrg }
64*90a8ff21Smrg
65*90a8ff21Smrg static int
mpc_set_type(mpc_t x,TYPE complex y,mpc_rnd_t rnd)66*90a8ff21Smrg mpc_set_type (mpc_t x, TYPE complex y, mpc_rnd_t rnd)
67*90a8ff21Smrg {
68*90a8ff21Smrg /* there is no mpc_set_float128c function */
69*90a8ff21Smrg mpfr_set_float128 (mpc_realref (x), crealf128 (y), MPC_RND_RE(rnd));
70*90a8ff21Smrg mpfr_set_float128 (mpc_imagref (x), cimagf128 (y), MPC_RND_IM(rnd));
71*90a8ff21Smrg }
72*90a8ff21Smrg
73*90a8ff21Smrg gmp_randstate_t state;
74*90a8ff21Smrg mpz_t expz; /* global variable used in mpcheck_random */
75*90a8ff21Smrg unsigned long seed = 0;
76*90a8ff21Smrg int verbose = 0;
77*90a8ff21Smrg mpfr_exp_t emin, emax;
78*90a8ff21Smrg
79*90a8ff21Smrg #include "mpcheck-common.c"
80*90a8ff21Smrg
81*90a8ff21Smrg #define FOO add
82*90a8ff21Smrg #define CFOO(x,y) (x+y)
83*90a8ff21Smrg #include "mpcheck-template3.c"
84*90a8ff21Smrg
85*90a8ff21Smrg #define FOO sub
86*90a8ff21Smrg #define CFOO(x,y) (x-y)
87*90a8ff21Smrg #include "mpcheck-template3.c"
88*90a8ff21Smrg
89*90a8ff21Smrg #define FOO mul
90*90a8ff21Smrg #define CFOO(x,y) (x*y)
91*90a8ff21Smrg #include "mpcheck-template3.c"
92*90a8ff21Smrg
93*90a8ff21Smrg #define FOO div
94*90a8ff21Smrg #define CFOO(x,y) (x/y)
95*90a8ff21Smrg #include "mpcheck-template3.c"
96*90a8ff21Smrg
97*90a8ff21Smrg #define FOO pow
98*90a8ff21Smrg #include "mpcheck-template3.c"
99*90a8ff21Smrg
100*90a8ff21Smrg #define FOO abs
101*90a8ff21Smrg #include "mpcheck-template2.c"
102*90a8ff21Smrg
103*90a8ff21Smrg #define FOO arg
104*90a8ff21Smrg #include "mpcheck-template2.c"
105*90a8ff21Smrg
106*90a8ff21Smrg #define FOO sqrt
107*90a8ff21Smrg #include "mpcheck-template1.c"
108*90a8ff21Smrg
109*90a8ff21Smrg #define FOO acos
110*90a8ff21Smrg #include "mpcheck-template1.c"
111*90a8ff21Smrg
112*90a8ff21Smrg #define FOO acosh
113*90a8ff21Smrg #include "mpcheck-template1.c"
114*90a8ff21Smrg
115*90a8ff21Smrg #define FOO asin
116*90a8ff21Smrg #include "mpcheck-template1.c"
117*90a8ff21Smrg
118*90a8ff21Smrg #define FOO asinh
119*90a8ff21Smrg #include "mpcheck-template1.c"
120*90a8ff21Smrg
121*90a8ff21Smrg #define FOO atan
122*90a8ff21Smrg #include "mpcheck-template1.c"
123*90a8ff21Smrg
124*90a8ff21Smrg #define FOO atanh
125*90a8ff21Smrg #include "mpcheck-template1.c"
126*90a8ff21Smrg
127*90a8ff21Smrg #define FOO cos
128*90a8ff21Smrg #include "mpcheck-template1.c"
129*90a8ff21Smrg
130*90a8ff21Smrg #define FOO cosh
131*90a8ff21Smrg #include "mpcheck-template1.c"
132*90a8ff21Smrg
133*90a8ff21Smrg #define FOO exp
134*90a8ff21Smrg #include "mpcheck-template1.c"
135*90a8ff21Smrg
136*90a8ff21Smrg #define FOO log
137*90a8ff21Smrg #include "mpcheck-template1.c"
138*90a8ff21Smrg
139*90a8ff21Smrg #define FOO log10
140*90a8ff21Smrg #include "mpcheck-template1.c"
141*90a8ff21Smrg
142*90a8ff21Smrg #define FOO sin
143*90a8ff21Smrg #include "mpcheck-template1.c"
144*90a8ff21Smrg
145*90a8ff21Smrg #define FOO sinh
146*90a8ff21Smrg #include "mpcheck-template1.c"
147*90a8ff21Smrg
148*90a8ff21Smrg #define FOO tan
149*90a8ff21Smrg #include "mpcheck-template1.c"
150*90a8ff21Smrg
151*90a8ff21Smrg #define FOO tanh
152*90a8ff21Smrg #include "mpcheck-template1.c"
153*90a8ff21Smrg
154*90a8ff21Smrg int
main(int argc,char * argv[])155*90a8ff21Smrg main (int argc, char *argv[])
156*90a8ff21Smrg {
157*90a8ff21Smrg mpfr_prec_t p = PRECISION; /* precision of 'double' */
158*90a8ff21Smrg unsigned long n = 1000000; /* default number of random tests per function */
159*90a8ff21Smrg
160*90a8ff21Smrg while (argc >= 2 && argv[1][0] == '-')
161*90a8ff21Smrg {
162*90a8ff21Smrg if (argc >= 3 && strcmp (argv[1], "-p") == 0)
163*90a8ff21Smrg {
164*90a8ff21Smrg p = atoi (argv[2]);
165*90a8ff21Smrg argc -= 2;
166*90a8ff21Smrg argv += 2;
167*90a8ff21Smrg }
168*90a8ff21Smrg else if (argc >= 3 && strcmp (argv[1], "-seed") == 0)
169*90a8ff21Smrg {
170*90a8ff21Smrg seed = atoi (argv[2]);
171*90a8ff21Smrg argc -= 2;
172*90a8ff21Smrg argv += 2;
173*90a8ff21Smrg }
174*90a8ff21Smrg else if (argc >= 3 && strcmp (argv[1], "-num") == 0)
175*90a8ff21Smrg {
176*90a8ff21Smrg n = atoi (argv[2]);
177*90a8ff21Smrg argc -= 2;
178*90a8ff21Smrg argv += 2;
179*90a8ff21Smrg }
180*90a8ff21Smrg else if (strcmp (argv[1], "-v") == 0)
181*90a8ff21Smrg {
182*90a8ff21Smrg verbose ++;
183*90a8ff21Smrg argc --;
184*90a8ff21Smrg argv ++;
185*90a8ff21Smrg }
186*90a8ff21Smrg else if (strcmp (argv[1], "-check") == 0)
187*90a8ff21Smrg {
188*90a8ff21Smrg recheck = 1;
189*90a8ff21Smrg argc --;
190*90a8ff21Smrg argv ++;
191*90a8ff21Smrg }
192*90a8ff21Smrg else
193*90a8ff21Smrg {
194*90a8ff21Smrg fprintf (stderr, "Unknown option %s\n", argv[1]);
195*90a8ff21Smrg exit (1);
196*90a8ff21Smrg }
197*90a8ff21Smrg }
198*90a8ff21Smrg
199*90a8ff21Smrg /* set exponent range */
200*90a8ff21Smrg emin = -EMAX - 64 + 4; /* should be -16444 like for long double */
201*90a8ff21Smrg emax = EMAX;
202*90a8ff21Smrg mpfr_set_emin (emin);
203*90a8ff21Smrg mpfr_set_emax (emax);
204*90a8ff21Smrg
205*90a8ff21Smrg gmp_randinit_default (state);
206*90a8ff21Smrg mpz_init (expz);
207*90a8ff21Smrg
208*90a8ff21Smrg printf ("Using GMP %s, MPFR %s\n", gmp_version, mpfr_get_version ());
209*90a8ff21Smrg
210*90a8ff21Smrg #ifdef __GNUC__
211*90a8ff21Smrg printf ("GNU libc version: %s\n", gnu_get_libc_version ());
212*90a8ff21Smrg printf ("GNU libc release: %s\n", gnu_get_libc_release ());
213*90a8ff21Smrg #endif
214*90a8ff21Smrg
215*90a8ff21Smrg if (seed == 0)
216*90a8ff21Smrg seed = getpid ();
217*90a8ff21Smrg printf ("Using random seed %lu\n", seed);
218*90a8ff21Smrg
219*90a8ff21Smrg /* (complex,complex) -> complex */
220*90a8ff21Smrg test_add (p, n);
221*90a8ff21Smrg test_sub (p, n);
222*90a8ff21Smrg test_mul (p, n);
223*90a8ff21Smrg test_div (p, n);
224*90a8ff21Smrg test_pow (p, n);
225*90a8ff21Smrg
226*90a8ff21Smrg /* complex -> real */
227*90a8ff21Smrg test_abs (p, n);
228*90a8ff21Smrg test_arg (p, n);
229*90a8ff21Smrg
230*90a8ff21Smrg /* complex -> complex */
231*90a8ff21Smrg test_sqrt (p, n);
232*90a8ff21Smrg test_acos (p, n);
233*90a8ff21Smrg test_acosh (p, n);
234*90a8ff21Smrg test_asin (p, n);
235*90a8ff21Smrg test_asinh (p, n);
236*90a8ff21Smrg test_atan (p, n);
237*90a8ff21Smrg test_atanh (p, n);
238*90a8ff21Smrg test_cos (p, n);
239*90a8ff21Smrg test_cosh (p, n);
240*90a8ff21Smrg test_exp (p, n);
241*90a8ff21Smrg test_log (p, n);
242*90a8ff21Smrg test_log10 (p, n);
243*90a8ff21Smrg test_sin (p, n);
244*90a8ff21Smrg test_sinh (p, n);
245*90a8ff21Smrg test_tan (p, n);
246*90a8ff21Smrg test_tanh (p, n);
247*90a8ff21Smrg
248*90a8ff21Smrg gmp_randclear (state);
249*90a8ff21Smrg mpz_clear (expz);
250*90a8ff21Smrg
251*90a8ff21Smrg report_maximal_errors ();
252*90a8ff21Smrg
253*90a8ff21Smrg return 0;
254*90a8ff21Smrg }
255