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