Set license using %license
[platform/upstream/mpfr.git] / tests / thypot.c
1 /* Test file for mpfr_hypot.
2
3 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel 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_hypot (z, x, y, MPFR_RNDN);
43   MPFR_ASSERTN(mpfr_nan_p (z));
44
45   mpfr_set_inf (x, 1);
46   mpfr_set_inf (y, -1);
47   mpfr_hypot (z, x, y, MPFR_RNDN);
48   MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
49
50   mpfr_set_inf (x, -1);
51   mpfr_set_nan (y);
52   mpfr_hypot (z, x, y, MPFR_RNDN);
53   MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
54
55   mpfr_set_nan (x);
56   mpfr_set_inf (y, -1);
57   mpfr_hypot (z, x, y, MPFR_RNDN);
58   MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0);
59
60   mpfr_clear (x);
61   mpfr_clear (y);
62   mpfr_clear (z);
63 }
64
65 static void
66 test_large (void)
67 {
68   mpfr_t x, y, z, t;
69
70   mpfr_init (x);
71   mpfr_init (y);
72   mpfr_init (z);
73   mpfr_init (t);
74
75   mpfr_set_ui (x, 21, MPFR_RNDN);
76   mpfr_set_ui (y, 28, MPFR_RNDN);
77   mpfr_set_ui (z, 35, MPFR_RNDN);
78
79   mpfr_mul_2ui (x, x, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
80   mpfr_mul_2ui (y, y, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
81   mpfr_mul_2ui (z, z, MPFR_EMAX_DEFAULT-6, MPFR_RNDN);
82
83   mpfr_hypot (t, x, y, MPFR_RNDN);
84   if (mpfr_cmp (z, t))
85     {
86       printf ("Error in test_large: got\n");
87       mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
88       printf ("\ninstead of\n");
89       mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
90       printf ("\n");
91       exit (1);
92     }
93
94   mpfr_set_prec (x, 53);
95   mpfr_set_prec (t, 53);
96   mpfr_set_prec (y, 53);
97   mpfr_set_str_binary (x, "0.11101100011110000011101000010101010011001101000001100E-1021");
98   mpfr_set_str_binary (y, "0.11111001010011000001110110001101011100001000010010100E-1021");
99   mpfr_hypot (t, x, y, MPFR_RNDN);
100   mpfr_set_str_binary (z, "0.101010111100110111101110111110100110010011001010111E-1020");
101   if (mpfr_cmp (z, t))
102     {
103       printf ("Error in test_large: got\n");
104       mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
105       printf ("\ninstead of\n");
106       mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
107       printf ("\n");
108       exit (1);
109     }
110
111   mpfr_set_prec (x, 240);
112   mpfr_set_prec (y, 22);
113   mpfr_set_prec (z, 2);
114   mpfr_set_prec (t, 2);
115   mpfr_set_str_binary (x, "0.100111011010010010110100000100000001100010011100110101101111111101011110111011011101010110100101111000111100010100110000100101011110111011100110100110100101110101101100011000001100000001111101110100100100011011011010110111100110010101000111e-7");
116   mpfr_set_str_binary (y, "0.1111000010000011000111E-10");
117   mpfr_hypot (t, x, y, MPFR_RNDN);
118   mpfr_set_str_binary (z, "0.11E-7");
119   if (mpfr_cmp (z, t))
120     {
121       printf ("Error in test_large: got\n");
122       mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);
123       printf ("\ninstead of\n");
124       mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
125       printf ("\n");
126       exit (1);
127     }
128
129   mpfr_clear (x);
130   mpfr_clear (y);
131   mpfr_clear (z);
132   mpfr_clear (t);
133 }
134
135 static void
136 test_small (void)
137 {
138   mpfr_t x, y, z1, z2;
139   int inex1, inex2;
140   unsigned int flags;
141
142   /* Test hypot(x,x) with x = 2^(emin-1). Result is x * sqrt(2). */
143   mpfr_inits2 (8, x, y, z1, z2, (mpfr_ptr) 0);
144   mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN);
145   mpfr_set_si_2exp (y, 1, mpfr_get_emin () - 1, MPFR_RNDN);
146   mpfr_set_ui (z1, 2, MPFR_RNDN);
147   inex1 = mpfr_sqrt (z1, z1, MPFR_RNDN);
148   inex2 = mpfr_mul (z1, z1, x, MPFR_RNDN);
149   MPFR_ASSERTN (inex2 == 0);
150   mpfr_clear_flags ();
151   inex2 = mpfr_hypot (z2, x, y, MPFR_RNDN);
152   flags = __gmpfr_flags;
153   if (mpfr_cmp (z1, z2) != 0)
154     {
155       printf ("Error in test_small%s\nExpected ",
156               ext ? ", extended exponent range" : "");
157       mpfr_out_str (stdout, 2, 0, z1, MPFR_RNDN);
158       printf ("\nGot      ");
159       mpfr_out_str (stdout, 2, 0, z2, MPFR_RNDN);
160       printf ("\n");
161       exit (1);
162     }
163   if (! SAME_SIGN (inex1, inex2))
164     {
165       printf ("Bad ternary value in test_small%s\nExpected %d, got %d\n",
166               ext ? ", extended exponent range" : "", inex1, inex2);
167       exit (1);
168     }
169   if (flags != MPFR_FLAGS_INEXACT)
170     {
171       printf ("Bad flags in test_small%s\nExpected %u, got %u\n",
172               ext ? ", extended exponent range" : "",
173               (unsigned int) MPFR_FLAGS_INEXACT, flags);
174       exit (1);
175     }
176   mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
177 }
178
179 static void
180 test_large_small (void)
181 {
182   mpfr_t x, y, z;
183   int inexact, inex2, r;
184
185   mpfr_init2 (x, 3);
186   mpfr_init2 (y, 2);
187   mpfr_init2 (z, 2);
188
189   mpfr_set_ui_2exp (x, 1, mpfr_get_emax () / 2, MPFR_RNDN);
190   mpfr_set_ui_2exp (y, 1, -1, MPFR_RNDN);
191   inexact = mpfr_hypot (z, x, y, MPFR_RNDN);
192   if (inexact >= 0 || mpfr_cmp (x, z))
193     {
194       printf ("Error 1 in test_large_small%s\n",
195               ext ? ", extended exponent range" : "");
196       exit (1);
197     }
198
199   mpfr_mul_ui (x, x, 5, MPFR_RNDN);
200   inexact = mpfr_hypot (z, x, y, MPFR_RNDN);
201   if (mpfr_cmp (x, z) >= 0)
202     {
203       printf ("Error 2 in test_large_small%s\n",
204               ext ? ", extended exponent range" : "");
205       printf ("x = ");
206       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
207       printf ("\n");
208       printf ("y = ");
209       mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
210       printf ("\n");
211       printf ("z = ");
212       mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
213       printf (" (in precision 2) instead of\n    ");
214       mpfr_out_str (stdout, 2, 2, x, MPFR_RNDU);
215       printf ("\n");
216       exit (1);
217     }
218
219   RND_LOOP(r)
220     {
221       mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN);
222       mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN);
223       inexact = mpfr_hypot (z, x, y, (mpfr_rnd_t) r);
224       inex2 = mpfr_add_ui (y, x, 1, (mpfr_rnd_t) r);
225       if (! mpfr_equal_p (y, z) || ! SAME_SIGN (inexact, inex2))
226         {
227           printf ("Error 3 in test_large_small, %s%s\n",
228                   mpfr_print_rnd_mode ((mpfr_rnd_t) r),
229                   ext ? ", extended exponent range" : "");
230           printf ("Expected ");
231           mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
232           printf (", inex = %d\n", inex2);
233           printf ("Got      ");
234           mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
235           printf (", inex = %d\n", inexact);
236           exit (1);
237         }
238     }
239
240   mpfr_clear (x);
241   mpfr_clear (y);
242   mpfr_clear (z);
243 }
244
245 static void
246 check_overflow (void)
247 {
248   mpfr_t x, y;
249   int inex, r;
250
251   mpfr_inits2 (8, x, y, (mpfr_ptr) 0);
252   mpfr_set_ui (x, 1, MPFR_RNDN);
253   mpfr_setmax (x, mpfr_get_emax ());
254
255   RND_LOOP(r)
256     {
257       mpfr_clear_overflow ();
258       inex = mpfr_hypot (y, x, x, (mpfr_rnd_t) r);
259       if (!mpfr_overflow_p ())
260         {
261           printf ("No overflow in check_overflow for %s%s\n",
262                   mpfr_print_rnd_mode ((mpfr_rnd_t) r),
263                   ext ? ", extended exponent range" : "");
264           exit (1);
265         }
266       MPFR_ASSERTN (MPFR_IS_POS (y));
267       if (r == MPFR_RNDZ || r == MPFR_RNDD)
268         {
269           MPFR_ASSERTN (inex < 0);
270           MPFR_ASSERTN (!mpfr_inf_p (y));
271           mpfr_nexttoinf (y);
272         }
273       else
274         {
275           MPFR_ASSERTN (inex > 0);
276         }
277       MPFR_ASSERTN (mpfr_inf_p (y));
278     }
279
280   mpfr_clears (x, y, (mpfr_ptr) 0);
281 }
282
283 #define TWO_ARGS
284 #define TEST_FUNCTION mpfr_hypot
285 #include "tgeneric.c"
286
287 static void
288 alltst (void)
289 {
290   mpfr_exp_t emin, emax;
291
292   ext = 0;
293   test_small ();
294   test_large_small ();
295   check_overflow ();
296
297   emin = mpfr_get_emin ();
298   emax = mpfr_get_emax ();
299   set_emin (MPFR_EMIN_MIN);
300   set_emax (MPFR_EMAX_MAX);
301   if (mpfr_get_emin () != emin || mpfr_get_emax () != emax)
302     {
303       ext = 1;
304       test_small ();
305       test_large_small ();
306       check_overflow ();
307       set_emin (emin);
308       set_emax (emax);
309     }
310 }
311
312 int
313 main (int argc, char *argv[])
314 {
315   tests_start_mpfr ();
316
317   special ();
318
319   test_large ();
320   alltst ();
321
322   test_generic (2, 100, 10);
323
324   tests_end_mpfr ();
325   return 0;
326 }