thypot.c revision 1.1.1.4 1 1.1 mrg /* Test file for mpfr_hypot.
2 1.1 mrg
3 1.1.1.4 mrg Copyright 2001-2018 Free Software Foundation, Inc.
4 1.1.1.3 mrg Contributed by the AriC and Caramba projects, INRIA.
5 1.1 mrg
6 1.1 mrg This file is part of the GNU MPFR Library.
7 1.1 mrg
8 1.1 mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
9 1.1 mrg it under the terms of the GNU Lesser General Public License as published by
10 1.1 mrg the Free Software Foundation; either version 3 of the License, or (at your
11 1.1 mrg option) any later version.
12 1.1 mrg
13 1.1 mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
14 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 1.1 mrg License for more details.
17 1.1 mrg
18 1.1 mrg You should have received a copy of the GNU Lesser General Public License
19 1.1 mrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20 1.1 mrg http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 1.1 mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22 1.1 mrg
23 1.1 mrg #include "mpfr-test.h"
24 1.1 mrg
25 1.1 mrg /* Non-zero when extended exponent range */
26 1.1 mrg static int ext = 0;
27 1.1 mrg
28 1.1 mrg static void
29 1.1 mrg special (void)
30 1.1 mrg {
31 1.1 mrg mpfr_t x, y, z;
32 1.1 mrg
33 1.1 mrg mpfr_init (x);
34 1.1 mrg mpfr_init (y);
35 1.1 mrg mpfr_init (z);
36 1.1 mrg
37 1.1 mrg mpfr_set_nan (x);
38 1.1.1.3 mrg mpfr_set_ui (y, 0, MPFR_RNDN);
39 1.1.1.3 mrg mpfr_hypot (z, x, x, MPFR_RNDN);
40 1.1.1.3 mrg MPFR_ASSERTN(mpfr_nan_p (z));
41 1.1 mrg mpfr_hypot (z, x, y, MPFR_RNDN);
42 1.1 mrg MPFR_ASSERTN(mpfr_nan_p (z));
43 1.1.1.3 mrg mpfr_hypot (z, y, x, MPFR_RNDN);
44 1.1.1.3 mrg MPFR_ASSERTN(mpfr_nan_p (z));
45 1.1 mrg
46 1.1 mrg mpfr_set_inf (x, 1);
47 1.1 mrg mpfr_set_inf (y, -1);
48 1.1 mrg mpfr_hypot (z, x, y, MPFR_RNDN);
49 1.1 mrg MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
50 1.1 mrg
51 1.1 mrg mpfr_set_inf (x, -1);
52 1.1 mrg mpfr_set_nan (y);
53 1.1 mrg mpfr_hypot (z, x, y, MPFR_RNDN);
54 1.1 mrg MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
55 1.1 mrg
56 1.1 mrg mpfr_set_nan (x);
57 1.1 mrg mpfr_set_inf (y, -1);
58 1.1 mrg mpfr_hypot (z, x, y, MPFR_RNDN);
59 1.1 mrg MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
60 1.1 mrg
61 1.1 mrg mpfr_clear (x);
62 1.1 mrg mpfr_clear (y);
63 1.1 mrg mpfr_clear (z);
64 1.1 mrg }
65 1.1 mrg
66 1.1 mrg static void
67 1.1 mrg test_large (void)
68 1.1 mrg {
69 1.1 mrg mpfr_t x, y, z, t;
70 1.1 mrg
71 1.1 mrg mpfr_init (x);
72 1.1 mrg mpfr_init (y);
73 1.1 mrg mpfr_init (z);
74 1.1 mrg mpfr_init (t);
75 1.1 mrg
76 1.1 mrg mpfr_set_ui (x, 21, MPFR_RNDN);
77 1.1 mrg mpfr_set_ui (y, 28, MPFR_RNDN);
78 1.1 mrg mpfr_set_ui (z, 35, MPFR_RNDN);
79 1.1 mrg
80 1.1 mrg mpfr_mul_2ui (x, x, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
81 1.1 mrg mpfr_mul_2ui (y, y, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
82 1.1 mrg mpfr_mul_2ui (z, z, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
83 1.1 mrg
84 1.1 mrg mpfr_hypot (t, x, y, MPFR_RNDN);
85 1.1 mrg if (mpfr_cmp (z, t))
86 1.1 mrg {
87 1.1 mrg printf ("Error in test_large: got\n");
88 1.1 mrg mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
89 1.1 mrg printf ("\ninstead of\n");
90 1.1 mrg mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
91 1.1 mrg printf ("\n");
92 1.1 mrg exit (1);
93 1.1 mrg }
94 1.1 mrg
95 1.1 mrg mpfr_set_prec (x, 53);
96 1.1 mrg mpfr_set_prec (t, 53);
97 1.1 mrg mpfr_set_prec (y, 53);
98 1.1 mrg mpfr_set_str_binary (x, "0.11101100011110000011101000010101010011001101000001100E-1021");
99 1.1 mrg mpfr_set_str_binary (y, "0.11111001010011000001110110001101011100001000010010100E-1021");
100 1.1 mrg mpfr_hypot (t, x, y, MPFR_RNDN);
101 1.1 mrg mpfr_set_str_binary (z, "0.101010111100110111101110111110100110010011001010111E-1020");
102 1.1 mrg if (mpfr_cmp (z, t))
103 1.1 mrg {
104 1.1 mrg printf ("Error in test_large: got\n");
105 1.1 mrg mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
106 1.1 mrg printf ("\ninstead of\n");
107 1.1 mrg mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
108 1.1 mrg printf ("\n");
109 1.1 mrg exit (1);
110 1.1 mrg }
111 1.1 mrg
112 1.1 mrg mpfr_set_prec (x, 240);
113 1.1 mrg mpfr_set_prec (y, 22);
114 1.1 mrg mpfr_set_prec (z, 2);
115 1.1 mrg mpfr_set_prec (t, 2);
116 1.1 mrg mpfr_set_str_binary (x, "0.100111011010010010110100000100000001100010011100110101101111111101011110111011011101010110100101111000111100010100110000100101011110111011100110100110100101110101101100011000001100000001111101110100100100011011011010110111100110010101000111e-7");
117 1.1 mrg mpfr_set_str_binary (y, "0.1111000010000011000111E-10");
118 1.1 mrg mpfr_hypot (t, x, y, MPFR_RNDN);
119 1.1 mrg mpfr_set_str_binary (z, "0.11E-7");
120 1.1 mrg if (mpfr_cmp (z, t))
121 1.1 mrg {
122 1.1 mrg printf ("Error in test_large: got\n");
123 1.1 mrg mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
124 1.1 mrg printf ("\ninstead of\n");
125 1.1 mrg mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
126 1.1 mrg printf ("\n");
127 1.1 mrg exit (1);
128 1.1 mrg }
129 1.1 mrg
130 1.1 mrg mpfr_clear (x);
131 1.1 mrg mpfr_clear (y);
132 1.1 mrg mpfr_clear (z);
133 1.1 mrg mpfr_clear (t);
134 1.1 mrg }
135 1.1 mrg
136 1.1 mrg static void
137 1.1 mrg test_small (void)
138 1.1 mrg {
139 1.1 mrg mpfr_t x, y, z1, z2;
140 1.1 mrg int inex1, inex2;
141 1.1 mrg unsigned int flags;
142 1.1 mrg
143 1.1 mrg /* Test hypot(x,x) with x = 2^(emin-1). Result is x * sqrt(2). */
144 1.1 mrg mpfr_inits2 (8, x, y, z1, z2, (mpfr_ptr) 0);
145 1.1 mrg mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN);
146 1.1 mrg mpfr_set_si_2exp (y, 1, mpfr_get_emin () - 1, MPFR_RNDN);
147 1.1 mrg mpfr_set_ui (z1, 2, MPFR_RNDN);
148 1.1 mrg inex1 = mpfr_sqrt (z1, z1, MPFR_RNDN);
149 1.1 mrg inex2 = mpfr_mul (z1, z1, x, MPFR_RNDN);
150 1.1 mrg MPFR_ASSERTN (inex2 == 0);
151 1.1 mrg mpfr_clear_flags ();
152 1.1 mrg inex2 = mpfr_hypot (z2, x, y, MPFR_RNDN);
153 1.1 mrg flags = __gmpfr_flags;
154 1.1 mrg if (mpfr_cmp (z1, z2) != 0)
155 1.1 mrg {
156 1.1 mrg printf ("Error in test_small%s\nExpected ",
157 1.1 mrg ext ? ", extended exponent range" : "");
158 1.1 mrg mpfr_out_str (stdout, 2, 0, z1, MPFR_RNDN);
159 1.1 mrg printf ("\nGot ");
160 1.1 mrg mpfr_out_str (stdout, 2, 0, z2, MPFR_RNDN);
161 1.1 mrg printf ("\n");
162 1.1 mrg exit (1);
163 1.1 mrg }
164 1.1 mrg if (! SAME_SIGN (inex1, inex2))
165 1.1 mrg {
166 1.1 mrg printf ("Bad ternary value in test_small%s\nExpected %d, got %d\n",
167 1.1 mrg ext ? ", extended exponent range" : "", inex1, inex2);
168 1.1 mrg exit (1);
169 1.1 mrg }
170 1.1 mrg if (flags != MPFR_FLAGS_INEXACT)
171 1.1 mrg {
172 1.1 mrg printf ("Bad flags in test_small%s\nExpected %u, got %u\n",
173 1.1 mrg ext ? ", extended exponent range" : "",
174 1.1 mrg (unsigned int) MPFR_FLAGS_INEXACT, flags);
175 1.1 mrg exit (1);
176 1.1 mrg }
177 1.1 mrg mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
178 1.1 mrg }
179 1.1 mrg
180 1.1 mrg static void
181 1.1 mrg test_large_small (void)
182 1.1 mrg {
183 1.1 mrg mpfr_t x, y, z;
184 1.1 mrg int inexact, inex2, r;
185 1.1 mrg
186 1.1 mrg mpfr_init2 (x, 3);
187 1.1 mrg mpfr_init2 (y, 2);
188 1.1 mrg mpfr_init2 (z, 2);
189 1.1 mrg
190 1.1 mrg mpfr_set_ui_2exp (x, 1, mpfr_get_emax () / 2, MPFR_RNDN);
191 1.1 mrg mpfr_set_ui_2exp (y, 1, -1, MPFR_RNDN);
192 1.1 mrg inexact = mpfr_hypot (z, x, y, MPFR_RNDN);
193 1.1 mrg if (inexact >= 0 || mpfr_cmp (x, z))
194 1.1 mrg {
195 1.1 mrg printf ("Error 1 in test_large_small%s\n",
196 1.1 mrg ext ? ", extended exponent range" : "");
197 1.1 mrg exit (1);
198 1.1 mrg }
199 1.1 mrg
200 1.1 mrg mpfr_mul_ui (x, x, 5, MPFR_RNDN);
201 1.1 mrg inexact = mpfr_hypot (z, x, y, MPFR_RNDN);
202 1.1 mrg if (mpfr_cmp (x, z) >= 0)
203 1.1 mrg {
204 1.1 mrg printf ("Error 2 in test_large_small%s\n",
205 1.1 mrg ext ? ", extended exponent range" : "");
206 1.1 mrg printf ("x = ");
207 1.1 mrg mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
208 1.1 mrg printf ("\n");
209 1.1 mrg printf ("y = ");
210 1.1 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
211 1.1 mrg printf ("\n");
212 1.1 mrg printf ("z = ");
213 1.1 mrg mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
214 1.1 mrg printf (" (in precision 2) instead of\n ");
215 1.1 mrg mpfr_out_str (stdout, 2, 2, x, MPFR_RNDU);
216 1.1 mrg printf ("\n");
217 1.1 mrg exit (1);
218 1.1 mrg }
219 1.1 mrg
220 1.1 mrg RND_LOOP(r)
221 1.1 mrg {
222 1.1 mrg mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN);
223 1.1 mrg mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN);
224 1.1 mrg inexact = mpfr_hypot (z, x, y, (mpfr_rnd_t) r);
225 1.1 mrg inex2 = mpfr_add_ui (y, x, 1, (mpfr_rnd_t) r);
226 1.1 mrg if (! mpfr_equal_p (y, z) || ! SAME_SIGN (inexact, inex2))
227 1.1 mrg {
228 1.1 mrg printf ("Error 3 in test_large_small, %s%s\n",
229 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r),
230 1.1 mrg ext ? ", extended exponent range" : "");
231 1.1 mrg printf ("Expected ");
232 1.1 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
233 1.1 mrg printf (", inex = %d\n", inex2);
234 1.1 mrg printf ("Got ");
235 1.1 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
236 1.1 mrg printf (", inex = %d\n", inexact);
237 1.1 mrg exit (1);
238 1.1 mrg }
239 1.1 mrg }
240 1.1 mrg
241 1.1 mrg mpfr_clear (x);
242 1.1 mrg mpfr_clear (y);
243 1.1 mrg mpfr_clear (z);
244 1.1 mrg }
245 1.1 mrg
246 1.1 mrg static void
247 1.1 mrg check_overflow (void)
248 1.1 mrg {
249 1.1 mrg mpfr_t x, y;
250 1.1 mrg int inex, r;
251 1.1 mrg
252 1.1 mrg mpfr_inits2 (8, x, y, (mpfr_ptr) 0);
253 1.1 mrg mpfr_set_ui (x, 1, MPFR_RNDN);
254 1.1 mrg mpfr_setmax (x, mpfr_get_emax ());
255 1.1 mrg
256 1.1 mrg RND_LOOP(r)
257 1.1 mrg {
258 1.1 mrg mpfr_clear_overflow ();
259 1.1 mrg inex = mpfr_hypot (y, x, x, (mpfr_rnd_t) r);
260 1.1 mrg if (!mpfr_overflow_p ())
261 1.1 mrg {
262 1.1 mrg printf ("No overflow in check_overflow for %s%s\n",
263 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r),
264 1.1 mrg ext ? ", extended exponent range" : "");
265 1.1 mrg exit (1);
266 1.1 mrg }
267 1.1 mrg MPFR_ASSERTN (MPFR_IS_POS (y));
268 1.1 mrg if (r == MPFR_RNDZ || r == MPFR_RNDD)
269 1.1 mrg {
270 1.1 mrg MPFR_ASSERTN (inex < 0);
271 1.1 mrg MPFR_ASSERTN (!mpfr_inf_p (y));
272 1.1 mrg mpfr_nexttoinf (y);
273 1.1 mrg }
274 1.1 mrg else
275 1.1 mrg {
276 1.1 mrg MPFR_ASSERTN (inex > 0);
277 1.1 mrg }
278 1.1 mrg MPFR_ASSERTN (mpfr_inf_p (y));
279 1.1 mrg }
280 1.1 mrg
281 1.1 mrg mpfr_clears (x, y, (mpfr_ptr) 0);
282 1.1 mrg }
283 1.1 mrg
284 1.1 mrg #define TWO_ARGS
285 1.1 mrg #define TEST_FUNCTION mpfr_hypot
286 1.1 mrg #include "tgeneric.c"
287 1.1 mrg
288 1.1 mrg static void
289 1.1 mrg alltst (void)
290 1.1 mrg {
291 1.1 mrg mpfr_exp_t emin, emax;
292 1.1 mrg
293 1.1 mrg ext = 0;
294 1.1 mrg test_small ();
295 1.1 mrg test_large_small ();
296 1.1 mrg check_overflow ();
297 1.1 mrg
298 1.1 mrg emin = mpfr_get_emin ();
299 1.1 mrg emax = mpfr_get_emax ();
300 1.1 mrg set_emin (MPFR_EMIN_MIN);
301 1.1 mrg set_emax (MPFR_EMAX_MAX);
302 1.1 mrg if (mpfr_get_emin () != emin || mpfr_get_emax () != emax)
303 1.1 mrg {
304 1.1 mrg ext = 1;
305 1.1 mrg test_small ();
306 1.1 mrg test_large_small ();
307 1.1 mrg check_overflow ();
308 1.1 mrg set_emin (emin);
309 1.1 mrg set_emax (emax);
310 1.1 mrg }
311 1.1 mrg }
312 1.1 mrg
313 1.1.1.4 mrg /* Test failing with GMP_CHECK_RANDOMIZE=1513841234 (overflow flag not set).
314 1.1.1.4 mrg The bug was in fact in mpfr_nexttoinf which didn't set the overflow flag. */
315 1.1.1.4 mrg static void
316 1.1.1.4 mrg bug20171221 (void)
317 1.1.1.4 mrg {
318 1.1.1.4 mrg mpfr_t x, u, y;
319 1.1.1.4 mrg int inex;
320 1.1.1.4 mrg mpfr_exp_t emax;
321 1.1.1.4 mrg
322 1.1.1.4 mrg mpfr_init2 (x, 12);
323 1.1.1.4 mrg mpfr_init2 (u, 12);
324 1.1.1.4 mrg mpfr_init2 (y, 11);
325 1.1.1.4 mrg mpfr_set_str_binary (x, "0.111111111110E0");
326 1.1.1.4 mrg mpfr_set_str_binary (u, "0.111011110100E-177");
327 1.1.1.4 mrg emax = mpfr_get_emax ();
328 1.1.1.4 mrg mpfr_set_emax (0);
329 1.1.1.4 mrg mpfr_clear_flags ();
330 1.1.1.4 mrg inex = mpfr_hypot (y, x, u, MPFR_RNDU);
331 1.1.1.4 mrg MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
332 1.1.1.4 mrg MPFR_ASSERTN(inex > 0);
333 1.1.1.4 mrg MPFR_ASSERTN(mpfr_inexflag_p ());
334 1.1.1.4 mrg MPFR_ASSERTN(mpfr_overflow_p ());
335 1.1.1.4 mrg mpfr_set_emax (emax);
336 1.1.1.4 mrg mpfr_clear (x);
337 1.1.1.4 mrg mpfr_clear (u);
338 1.1.1.4 mrg mpfr_clear (y);
339 1.1.1.4 mrg }
340 1.1.1.4 mrg
341 1.1 mrg int
342 1.1 mrg main (int argc, char *argv[])
343 1.1 mrg {
344 1.1 mrg tests_start_mpfr ();
345 1.1 mrg
346 1.1.1.4 mrg bug20171221 ();
347 1.1 mrg special ();
348 1.1 mrg
349 1.1 mrg test_large ();
350 1.1 mrg alltst ();
351 1.1 mrg
352 1.1.1.4 mrg test_generic (MPFR_PREC_MIN, 100, 10);
353 1.1 mrg
354 1.1 mrg tests_end_mpfr ();
355 1.1 mrg return 0;
356 1.1 mrg }
357