tsqr.c revision 1.1.1.2 1 1.1 mrg /* tsqr -- test file for mpc_sqr.
2 1.1 mrg
3 1.1.1.2 mrg Copyright (C) 2002, 2005, 2008, 2010, 2011, 2012, 2013 INRIA
4 1.1 mrg
5 1.1 mrg This file is part of GNU MPC.
6 1.1 mrg
7 1.1 mrg GNU MPC is free software; you can redistribute it and/or modify it under
8 1.1 mrg the terms of the GNU Lesser General Public License as published by the
9 1.1 mrg Free Software Foundation; either version 3 of the License, or (at your
10 1.1 mrg option) any later version.
11 1.1 mrg
12 1.1 mrg GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 1.1 mrg FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15 1.1 mrg more details.
16 1.1 mrg
17 1.1 mrg You should have received a copy of the GNU Lesser General Public License
18 1.1 mrg along with this program. If not, see http://www.gnu.org/licenses/ .
19 1.1 mrg */
20 1.1 mrg
21 1.1 mrg #include <stdlib.h>
22 1.1 mrg #include "mpc-tests.h"
23 1.1 mrg
24 1.1 mrg static void
25 1.1 mrg cmpsqr (mpc_srcptr x, mpc_rnd_t rnd)
26 1.1 mrg /* computes the square of x with the specific function or by simple */
27 1.1 mrg /* multiplication using the rounding mode rnd and compares the results */
28 1.1 mrg /* and return values. */
29 1.1 mrg /* In our current test suite, the real and imaginary parts of x have */
30 1.1 mrg /* the same precision, and we use this precision also for the result. */
31 1.1 mrg /* Furthermore, we check whether computing the square in the same */
32 1.1 mrg /* place yields the same result. */
33 1.1 mrg /* We also compute the result with four times the precision and check */
34 1.1 mrg /* whether the rounding is correct. Error reports in this part of the */
35 1.1 mrg /* algorithm might still be wrong, though, since there are two */
36 1.1 mrg /* consecutive roundings. */
37 1.1 mrg {
38 1.1 mrg mpc_t z, t, u;
39 1.1 mrg int inexact_z, inexact_t;
40 1.1 mrg
41 1.1 mrg mpc_init2 (z, MPC_MAX_PREC (x));
42 1.1 mrg mpc_init2 (t, MPC_MAX_PREC (x));
43 1.1 mrg mpc_init2 (u, 4 * MPC_MAX_PREC (x));
44 1.1 mrg
45 1.1 mrg inexact_z = mpc_sqr (z, x, rnd);
46 1.1 mrg inexact_t = mpc_mul (t, x, x, rnd);
47 1.1 mrg
48 1.1 mrg if (mpc_cmp (z, t))
49 1.1 mrg {
50 1.1 mrg fprintf (stderr, "sqr and mul differ for rnd=(%s,%s) \nx=",
51 1.1 mrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
52 1.1 mrg mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
53 1.1 mrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
54 1.1 mrg fprintf (stderr, "\nmpc_sqr gives ");
55 1.1 mrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
56 1.1 mrg fprintf (stderr, "\nmpc_mul gives ");
57 1.1 mrg mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
58 1.1 mrg fprintf (stderr, "\n");
59 1.1 mrg exit (1);
60 1.1 mrg }
61 1.1 mrg if (inexact_z != inexact_t)
62 1.1 mrg {
63 1.1 mrg fprintf (stderr, "The return values of sqr and mul differ for rnd=(%s,%s) \nx= ",
64 1.1 mrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
65 1.1 mrg mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
66 1.1 mrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
67 1.1 mrg fprintf (stderr, "\nx^2=");
68 1.1 mrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
69 1.1 mrg fprintf (stderr, "\nmpc_sqr gives %i", inexact_z);
70 1.1 mrg fprintf (stderr, "\nmpc_mul gives %i", inexact_t);
71 1.1 mrg fprintf (stderr, "\n");
72 1.1 mrg exit (1);
73 1.1 mrg }
74 1.1 mrg
75 1.1 mrg mpc_set (t, x, MPC_RNDNN);
76 1.1 mrg inexact_t = mpc_sqr (t, t, rnd);
77 1.1 mrg if (mpc_cmp (z, t))
78 1.1 mrg {
79 1.1 mrg fprintf (stderr, "sqr and sqr in place differ for rnd=(%s,%s) \nx=",
80 1.1 mrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
81 1.1 mrg mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
82 1.1 mrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
83 1.1 mrg fprintf (stderr, "\nmpc_sqr gives ");
84 1.1 mrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
85 1.1 mrg fprintf (stderr, "\nmpc_sqr in place gives ");
86 1.1 mrg mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
87 1.1 mrg fprintf (stderr, "\n");
88 1.1 mrg exit (1);
89 1.1 mrg }
90 1.1 mrg if (inexact_z != inexact_t)
91 1.1 mrg {
92 1.1 mrg fprintf (stderr, "The return values of sqr and sqr in place differ for rnd=(%s,%s) \nx= ",
93 1.1 mrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
94 1.1 mrg mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
95 1.1 mrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
96 1.1 mrg fprintf (stderr, "\nx^2=");
97 1.1 mrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
98 1.1 mrg fprintf (stderr, "\nmpc_sqr gives %i", inexact_z);
99 1.1 mrg fprintf (stderr, "\nmpc_sqr in place gives %i", inexact_t);
100 1.1 mrg fprintf (stderr, "\n");
101 1.1 mrg exit (1);
102 1.1 mrg }
103 1.1 mrg
104 1.1 mrg mpc_sqr (u, x, rnd);
105 1.1 mrg mpc_set (t, u, rnd);
106 1.1 mrg if (mpc_cmp (z, t))
107 1.1 mrg {
108 1.1 mrg fprintf (stderr, "rounding in sqr might be incorrect for rnd=(%s,%s) \nx=",
109 1.1 mrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
110 1.1 mrg mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
111 1.1 mrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
112 1.1 mrg fprintf (stderr, "\nmpc_sqr gives ");
113 1.1 mrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
114 1.1 mrg fprintf (stderr, "\nmpc_sqr quadruple precision gives ");
115 1.1 mrg mpc_out_str (stderr, 2, 0, u, MPC_RNDNN);
116 1.1 mrg fprintf (stderr, "\nand is rounded to ");
117 1.1 mrg mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
118 1.1 mrg fprintf (stderr, "\n");
119 1.1 mrg exit (1);
120 1.1 mrg }
121 1.1 mrg
122 1.1 mrg mpc_clear (z);
123 1.1 mrg mpc_clear (t);
124 1.1 mrg mpc_clear (u);
125 1.1 mrg }
126 1.1 mrg
127 1.1 mrg
128 1.1 mrg static void
129 1.1 mrg testsqr (long a, long b, mpfr_prec_t prec, mpc_rnd_t rnd)
130 1.1 mrg {
131 1.1 mrg mpc_t x;
132 1.1 mrg
133 1.1 mrg mpc_init2 (x, prec);
134 1.1 mrg
135 1.1 mrg mpc_set_si_si (x, a, b, rnd);
136 1.1 mrg
137 1.1 mrg cmpsqr (x, rnd);
138 1.1 mrg
139 1.1 mrg mpc_clear (x);
140 1.1 mrg }
141 1.1 mrg
142 1.1 mrg
143 1.1 mrg static void
144 1.1 mrg reuse_bug (void)
145 1.1 mrg {
146 1.1 mrg mpc_t z1;
147 1.1 mrg
148 1.1 mrg /* reuse bug found by Paul Zimmermann 20081021 */
149 1.1 mrg mpc_init2 (z1, 2);
150 1.1 mrg /* RE (z1^2) overflows, IM(z^2) = -0 */
151 1.1.1.2 mrg mpfr_set_str (mpc_realref (z1), "0.11", 2, MPFR_RNDN);
152 1.1.1.2 mrg mpfr_mul_2si (mpc_realref (z1), mpc_realref (z1), mpfr_get_emax (), MPFR_RNDN);
153 1.1.1.2 mrg mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
154 1.1 mrg mpc_conj (z1, z1, MPC_RNDNN);
155 1.1 mrg mpc_sqr (z1, z1, MPC_RNDNN);
156 1.1 mrg if (!mpfr_inf_p (mpc_realref (z1)) || mpfr_signbit (mpc_realref (z1))
157 1.1 mrg ||!mpfr_zero_p (mpc_imagref (z1)) || !mpfr_signbit (mpc_imagref (z1)))
158 1.1 mrg {
159 1.1 mrg printf ("Error: Regression, bug 20081021 reproduced\n");
160 1.1 mrg MPC_OUT (z1);
161 1.1 mrg exit (1);
162 1.1 mrg }
163 1.1 mrg
164 1.1 mrg mpc_clear (z1);
165 1.1 mrg }
166 1.1 mrg
167 1.1.1.2 mrg #define MPC_FUNCTION_CALL \
168 1.1.1.2 mrg P[0].mpc_inex = mpc_sqr (P[1].mpc, P[2].mpc, P[3].mpc_rnd)
169 1.1.1.2 mrg #define MPC_FUNCTION_CALL_REUSE_OP1 \
170 1.1.1.2 mrg P[0].mpc_inex = mpc_sqr (P[1].mpc, P[1].mpc, P[3].mpc_rnd)
171 1.1.1.2 mrg
172 1.1.1.2 mrg #include "data_check.tpl"
173 1.1.1.2 mrg #include "tgeneric.tpl"
174 1.1.1.2 mrg
175 1.1 mrg int
176 1.1 mrg main (void)
177 1.1 mrg {
178 1.1 mrg test_start ();
179 1.1 mrg
180 1.1 mrg testsqr (247, -65, 8, 24);
181 1.1 mrg testsqr (5, -896, 3, 2);
182 1.1 mrg testsqr (-3, -512, 2, 16);
183 1.1 mrg testsqr (266013312, 121990769, 27, 0);
184 1.1 mrg testsqr (170, 9, 8, 0);
185 1.1 mrg testsqr (768, 85, 8, 16);
186 1.1 mrg testsqr (145, 1816, 8, 24);
187 1.1 mrg testsqr (0, 1816, 8, 24);
188 1.1 mrg testsqr (145, 0, 8, 24);
189 1.1 mrg
190 1.1.1.2 mrg data_check_template ("sqr.dsc", "sqr.dat");
191 1.1.1.2 mrg
192 1.1.1.2 mrg tgeneric_template ("sqr.dsc", 2, 1024, 1, 1024);
193 1.1 mrg
194 1.1 mrg reuse_bug ();
195 1.1 mrg
196 1.1 mrg test_end ();
197 1.1 mrg
198 1.1 mrg return 0;
199 1.1 mrg }
200