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