xref: /netbsd-src/external/lgpl3/mpc/dist/tests/texceptions.c (revision 367b82799ab709709d3c3b541df56a2a14644d3e)
1 /* exceptions -- test file for exceptions
2 
3 Copyright (C) 2015, 2022 INRIA
4 
5 This file is part of GNU MPC.
6 
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.
11 
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
15 more details.
16 
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/ .
19 */
20 
21 #include "mpc-tests.h"
22 
23 /* Return non-zero if 'rnd' rounds towards zero, for a number of sign 'sgn' */
24 #define MPC_IS_LIKE_RNDZ(rnd, sgn) \
25   ((rnd==MPFR_RNDZ) || (sgn<0 && rnd==MPFR_RNDU) || (sgn>0 && rnd==MPFR_RNDD))
26 
27 #define MPFR_SGN(x) (mpfr_signbit (x) ? -1 : 1)
28 
29 static void
foo(int f (mpc_ptr,mpc_srcptr,mpc_rnd_t),const char * s)30 foo (int f(mpc_ptr, mpc_srcptr, mpc_rnd_t), const char *s)
31 {
32   mpc_t z, t;
33   mpfr_rnd_t rnd_re, rnd_im;
34   mpc_rnd_t rnd;
35 #define N 5
36   mpfr_exp_t exy[N][2] = {{200, 800}, {800, 200}, {-50, 50}, {-10, 1000},
37                           {0, 1000}};
38   int n, inex, inex_re, inex_im, sgn;
39 
40   mpc_init2 (z, MPFR_PREC_MIN);
41   mpc_init2 (t, MPFR_PREC_MIN);
42   for (n = 0; n < N; n++)
43     for (sgn = 0; sgn < 4; sgn++)
44     {
45       if (exy[n][0])
46         mpfr_set_ui_2exp (mpc_realref (z), 1, exy[n][0], MPFR_RNDN);
47       else
48         mpfr_set_ui (mpc_realref (z), 0, MPFR_RNDN);
49       if (sgn & 1)
50         mpfr_neg (mpc_realref (z), mpc_realref (z), MPFR_RNDN);
51       if (exy[n][1])
52         mpfr_set_ui_2exp (mpc_imagref (z), 1, exy[n][1], MPFR_RNDN);
53       else
54         mpfr_set_ui (mpc_imagref (z), 0, MPFR_RNDN);
55       if (sgn & 2)
56         mpfr_neg (mpc_imagref (z), mpc_imagref (z), MPFR_RNDN);
57 
58       inex = f (t, z, MPC_RNDZZ);
59       inex_re = MPC_INEX_RE(inex);
60       inex_im = MPC_INEX_IM(inex);
61 
62       if (inex_re != 0 && mpfr_inf_p (mpc_realref (t)))
63         {
64           fprintf (stderr, "Error, wrong real part with rounding towards zero\n");
65           fprintf (stderr, "f = %s\n", s);
66           fprintf (stderr, "z=");
67           mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
68           fprintf (stderr, "\nt=");
69           mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
70           fprintf (stderr, "\n");
71           exit (1);
72         }
73 
74       if (inex_im != 0 && mpfr_inf_p (mpc_imagref (t)))
75         {
76           fprintf (stderr, "Error, wrong imag part with rounding towards zero\n");
77           fprintf (stderr, "f = %s\n", s);
78           fprintf (stderr, "z=");
79           mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
80           fprintf (stderr, "\nt=");
81           mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
82           fprintf (stderr, "\n");
83           exit (1);
84         }
85 
86       rnd_re = mpfr_signbit (mpc_realref (t)) == 0 ? MPFR_RNDU : MPFR_RNDD;
87       rnd_im = mpfr_signbit (mpc_imagref (t)) == 0 ? MPFR_RNDU : MPFR_RNDD;
88       rnd = MPC_RND(rnd_re,rnd_im); /* round away */
89 
90       inex = f (t, z, rnd);
91       inex_re = MPC_INEX_RE(inex);
92       inex_im = MPC_INEX_IM(inex);
93 
94       if (inex_re != 0 && mpfr_zero_p (mpc_realref (t)))
95         {
96           fprintf (stderr, "Error, wrong real part with rounding away from zero\n");
97           fprintf (stderr, "f = %s\n", s);
98           fprintf (stderr, "z=");
99           mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
100           fprintf (stderr, "\nt=");
101           mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
102           fprintf (stderr, "\n");
103           fprintf (stderr, "rnd=%s\n", mpfr_print_rnd_mode (rnd_re));
104           exit (1);
105         }
106 
107       if (inex_im != 0 && mpfr_zero_p (mpc_imagref (t)))
108         {
109           fprintf (stderr, "Error, wrong imag part with rounding away from zero\n");
110           fprintf (stderr, "f = %s\n", s);
111           fprintf (stderr, "z=");
112           mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
113           fprintf (stderr, "\nt=");
114           mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
115           fprintf (stderr, "\n");
116           fprintf (stderr, "rnd=%s\n", mpfr_print_rnd_mode (rnd_im));
117           exit (1);
118         }
119     }
120 
121   mpc_clear (z);
122   mpc_clear (t);
123 }
124 
125 int
main(void)126 main (void)
127 {
128   test_start ();
129 
130   foo (mpc_sqr, "sqr");
131   foo (mpc_conj, "conj");
132   foo (mpc_neg, "neg");
133   foo (mpc_sqrt, "sqrt");
134   foo (mpc_set, "set");
135   foo (mpc_proj, "proj");
136   foo (mpc_exp, "exp");
137   foo (mpc_exp, "exp");
138   foo (mpc_log, "log");
139   foo (mpc_log10, "log10");
140   foo (mpc_sin, "sin");
141   foo (mpc_cos, "cos");
142   foo (mpc_tan, "tan");
143   foo (mpc_sinh, "sinh");
144   foo (mpc_cosh, "cosh");
145   foo (mpc_tanh, "tanh");
146   foo (mpc_asin, "asin");
147   foo (mpc_acos, "acos");
148   foo (mpc_atan, "atan");
149   foo (mpc_asinh, "asinh");
150   foo (mpc_acosh, "acosh");
151   foo (mpc_atanh, "atanh");
152 
153   test_end ();
154 
155   return 0;
156 }
157