1/* Test file for mpfr_atan and mpfr_atan2.
2
3Copyright 2001-2023 Free Software Foundation, Inc.
4Contributed by the AriC and Caramba projects, INRIA.
5
6This file is part of the GNU MPFR Library.
7
8The GNU MPFR Library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as published by
10the Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
12
13The GNU MPFR Library is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16License for more details.
17
18You should have received a copy of the GNU Lesser General Public License
19along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23#include "mpfr-test.h"
24
25static void
26special (void)
27{
28  mpfr_t x, y, z;
29  int r;
30  int i;
31
32  mpfr_init2 (x, 53);
33  mpfr_init2 (y, 53);
34  mpfr_init2 (z, 53);
35
36  mpfr_set_str_binary (x, "1.0000100110000001100111100011001110101110100111011101");
37  mpfr_set_str_binary (y, "1.1001101101110100101100110011011101101000011010111110e-1");
38  mpfr_atan (z, x, MPFR_RNDN);
39  if (mpfr_cmp (y, z))
40    {
41      printf ("Error in mpfr_atan for prec=53, rnd=MPFR_RNDN\n");
42      printf ("x=");
43      mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
44      printf ("\nexpected ");
45      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
46      printf ("\ngot      ");
47      mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
48      printf ("\n");
49      exit (1);
50    }
51
52  /* atan(+Inf) = Pi/2 */
53  RND_LOOP (r)
54    {
55      mpfr_set_inf (x, 1);
56      mpfr_atan (y, x, (mpfr_rnd_t) r);
57      mpfr_const_pi (x, (mpfr_rnd_t) r);
58      mpfr_div_2ui (x, x, 1, (mpfr_rnd_t) r);
59      if (mpfr_cmp (x, y))
60        {
61          printf ("Error: mpfr_atan(+Inf), rnd=%s\n",
62                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
63          exit (1);
64        }
65    }
66
67  /* atan(-Inf) = - Pi/2 */
68  RND_LOOP (r)
69    {
70      mpfr_set_inf (x, -1);
71      mpfr_atan (y, x, (mpfr_rnd_t) r);
72      mpfr_const_pi (x, MPFR_INVERT_RND((mpfr_rnd_t) r));
73      mpfr_neg (x, x, (mpfr_rnd_t) r);
74      mpfr_div_2ui (x, x, 1, (mpfr_rnd_t) r);
75      if (mpfr_cmp (x, y))
76        {
77          printf ("Error: mpfr_atan(-Inf), rnd=%s\n",
78                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
79          exit (1);
80        }
81    }
82
83  /* atan(NaN) = NaN */
84  mpfr_set_nan (x);
85  mpfr_atan (y, x, MPFR_RNDN);
86  if (!mpfr_nan_p (y))
87    {
88      printf ("Error: mpfr_atan(NaN) <> NaN\n");
89      exit (1);
90    }
91
92  /* atan(+/-0) = +/-0 */
93  mpfr_set_ui (x, 0, MPFR_RNDN);
94  MPFR_SET_NEG (y);
95  mpfr_atan (y, x, MPFR_RNDN);
96  if (mpfr_cmp_ui (y, 0) || MPFR_IS_NEG (y))
97    {
98      printf ("Error: mpfr_atan (+0) <> +0\n");
99      exit (1);
100    }
101  mpfr_atan (x, x, MPFR_RNDN);
102  if (mpfr_cmp_ui (x, 0) || MPFR_IS_NEG (x))
103    {
104      printf ("Error: mpfr_atan (+0) <> +0 (in place)\n");
105      exit (1);
106    }
107  mpfr_neg (x, x, MPFR_RNDN);
108  MPFR_SET_POS (y);
109  mpfr_atan (y, x, MPFR_RNDN);
110  if (mpfr_cmp_ui (y, 0) || MPFR_IS_POS (y))
111    {
112      printf ("Error: mpfr_atan (-0) <> -0\n");
113      exit (1);
114    }
115  mpfr_atan (x, x, MPFR_RNDN);
116  if (mpfr_cmp_ui (x, 0) || MPFR_IS_POS (x))
117    {
118      printf ("Error: mpfr_atan (-0) <> -0 (in place)\n");
119      exit (1);
120    }
121
122  mpfr_set_prec (x, 32);
123  mpfr_set_prec (y, 32);
124
125  /* test one random positive argument */
126  mpfr_set_str_binary (x, "0.10000100001100101001001001011001");
127  mpfr_atan (x, x, MPFR_RNDN);
128  mpfr_set_str_binary (y, "0.1111010000001111001111000000011E-1");
129  if (mpfr_cmp (x, y))
130    {
131      printf ("Error in mpfr_atan (1)\n");
132      exit (1);
133    }
134
135  /* test one random negative argument */
136  mpfr_set_str_binary (x, "-0.1100001110110000010101011001011");
137  mpfr_atan (x, x, MPFR_RNDN);
138  mpfr_set_str_binary (y, "-0.101001110001010010110001110001");
139  if (mpfr_cmp (x, y))
140    {
141      printf ("Error in mpfr_atan (2)\n");
142      mpfr_dump (x);
143      mpfr_dump (y);
144      exit (1);
145    }
146
147  mpfr_set_prec (x, 3);
148  mpfr_set_prec (y, 192);
149  mpfr_set_prec (z, 192);
150  mpfr_set_str_binary (x, "-0.100e1");
151  mpfr_atan (z, x, MPFR_RNDD);
152  mpfr_set_str_binary (y, "-0.110010010000111111011010101000100010000101101000110000100011010011000100110001100110001010001011100000001101110000011100110100010010100100000010010011100000100010001010011001111100110001110101");
153  if (mpfr_cmp (z, y))
154    {
155      printf ("Error in mpfr_atan (3)\n");
156      printf ("Expected "); mpfr_dump (y);
157      printf ("Got      "); mpfr_dump (z);
158      exit (1);
159    }
160
161  /* Test regression */
162  mpfr_set_prec (x, 51);
163  mpfr_set_prec (y, 51);
164  mpfr_set_str_binary (x,
165           "0.101100100000101111111010001111111000001000000000000E-11");
166  i = mpfr_atan (y, x, MPFR_RNDN);
167  if (mpfr_cmp_str (y,
168   "1.01100100000101111111001110011001010110100100000000e-12", 2, MPFR_RNDN)
169      || i >= 0)
170    {
171      printf ("Wrong Regression test (%d)\n", i);
172      mpfr_dump (y);
173      exit (1);
174    }
175
176  mpfr_set_si (x, -1, MPFR_RNDN);
177  mpfr_atan (x, x, MPFR_RNDN);
178  MPFR_ASSERTN (MPFR_IS_NEG (x));
179
180  /* Test regression */
181  mpfr_set_prec (x, 48);
182  mpfr_set_prec (y, 48);
183  mpfr_set_str_binary (x, "1.11001110010000011111100000010000000000000000000e-19");
184  mpfr_atan (y, x, MPFR_RNDD);
185  if (mpfr_cmp_str (y, "0.111001110010000011111100000001111111110000010011E-18", 2, MPFR_RNDN))
186    {
187      printf ("Error in mpfr_atan (4)\n");
188      printf ("Input    1.11001110010000011111100000010000000000000000000e-19 [prec=48]\n");
189      printf ("Expected 0.111001110010000011111100000001111111110000010011E-18\n");
190      printf ("Got      "); mpfr_dump (y);
191      exit (1);
192    }
193
194  mpfr_clear (x);
195  mpfr_clear (y);
196  mpfr_clear (z);
197}
198
199#define TEST_FUNCTION mpfr_atan
200#define test_generic test_generic_atan
201#define RAND_FUNCTION(x) (mpfr_urandomb (x, RANDS), mpfr_mul_2si (x, x, (randlimb () %1000-500), MPFR_RNDN))
202#include "tgeneric.c"
203
204#define TEST_FUNCTION mpfr_atan2
205#define TWO_ARGS
206#define test_generic test_generic_atan2
207#include "tgeneric.c"
208
209#define TEST_FUNCTION mpfr_atan2
210#define TWO_ARGS
211#define RAND_FUNCTION(x) (mpfr_urandomb (x, RANDS), MPFR_SET_NEG (x))
212#define test_generic test_generic_atan2_neg
213#include "tgeneric.c"
214
215static void
216special_overflow (void)
217{
218  mpfr_t x, y;
219  mpfr_exp_t emin, emax;
220
221  emin = mpfr_get_emin ();
222  emax = mpfr_get_emax ();
223
224  set_emin (-125);
225  set_emax (128);
226  mpfr_init2 (x, 24);
227  mpfr_init2 (y, 48);
228  mpfr_set_str_binary (x, "0.101101010001001101111010E0");
229  mpfr_atan (y, x, MPFR_RNDN);
230  if (mpfr_cmp_str (y, "0.100111011001100111000010111101000111010101011110E0",
231                    2, MPFR_RNDN))
232    {
233      printf("Special Overflow error.\n");
234      mpfr_dump (y);
235      exit (1);
236    }
237
238  /* intermediate Pi overflows while atan(+Inf) = Pi/2 is representable */
239  set_emax (1);
240  mpfr_set_inf (x, +1);
241  mpfr_clear_flags ();
242  mpfr_atan (y, x, MPFR_RNDN);
243  if (mpfr_cmp_str (y, "C90FDAA22169p-47", 16, MPFR_RNDN)
244      || mpfr_overflow_p ())
245    {
246      printf("atan(+Inf) = Pi/2 should not overflow when emax = %ld\n",
247             (long int) mpfr_get_emax ());
248      mpfr_dump (y);
249      exit (1);
250    }
251
252  /* atan(+Inf) = Pi/2 underflows */
253  set_emax (128);
254  set_emin (3);
255  mpfr_clear_flags ();
256  mpfr_atan (y, x, MPFR_RNDN);
257  if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ())
258    {
259      printf("atan(+Inf) = Pi/2 should underflow when emin = %ld\n",
260             (long int) mpfr_get_emin ());
261      mpfr_dump (y);
262      exit (1);
263    }
264
265  /* intermediate Pi overflows while atan(+1) = Pi/4 is representable */
266  set_emax (1);
267  set_emin (-128);
268  mpfr_set_ui (x, 1, MPFR_RNDN);
269  mpfr_clear_flags ();
270  mpfr_atan (y, x, MPFR_RNDN);
271  if (mpfr_cmp_str (y, "C90FDAA22169p-48", 16, MPFR_RNDN)
272      || mpfr_overflow_p ())
273    {
274      printf("atan(+1) = Pi/4 should not overflow when emax = %ld\n",
275             (long int) mpfr_get_emax ());
276      mpfr_dump (y);
277      exit (1);
278    }
279
280  /* atan(+1) = Pi/4 underflows and is rounded up to 1 */
281  set_emax (128);
282  set_emin (1);
283  mpfr_set_prec (y, 2);
284  mpfr_clear_flags ();
285  mpfr_atan (y, x, MPFR_RNDN);
286  if (mpfr_cmp_ui (y, 1) || !mpfr_underflow_p ())
287    {
288      printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n",
289             (long int) mpfr_get_emin ());
290      mpfr_dump (y);
291      exit (1);
292    }
293
294  /* atan(+1) = Pi/4 underflows and is rounded down to 0 */
295  mpfr_clear_flags ();
296  mpfr_atan (y, x, MPFR_RNDD);
297  if (mpfr_cmp_ui (y, 0) || !mpfr_underflow_p ())
298    {
299      printf("atan(+1) = Pi/4 should underflow when emin = %+ld\n",
300             (long int) mpfr_get_emin ());
301      mpfr_dump (y);
302      exit (1);
303    }
304
305  mpfr_clear (y);
306  mpfr_clear (x);
307  set_emin (emin);
308  set_emax (emax);
309}
310
311static void
312special_atan2 (void)
313{
314  mpfr_t x, y, z;
315
316  mpfr_inits2 (4, x, y, z, (mpfr_ptr) 0);
317
318  /* Anything with NAN should be set to NAN */
319  mpfr_set_ui (y, 0, MPFR_RNDN);
320  mpfr_set_nan (x);
321  mpfr_atan2 (z, y, x, MPFR_RNDN);
322  MPFR_ASSERTN (MPFR_IS_NAN (z));
323  mpfr_swap (x, y);
324  mpfr_atan2 (z, y, x, MPFR_RNDN);
325  MPFR_ASSERTN (MPFR_IS_NAN (z));
326
327  /* 0+ 0+ --> 0+ */
328  mpfr_set_ui (y, 0, MPFR_RNDN);
329  mpfr_atan2 (z, y, x, MPFR_RNDN);
330  MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
331  /* 0- 0+ --> 0- */
332  MPFR_CHANGE_SIGN (y);
333  mpfr_atan2 (z, y, x, MPFR_RNDN);
334  MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
335  /* 0- 0- --> -PI */
336  MPFR_CHANGE_SIGN (x);
337  mpfr_atan2 (z, y, x, MPFR_RNDN);
338  MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
339  /* 0+ 0- --> +PI */
340  MPFR_CHANGE_SIGN (y);
341  mpfr_atan2 (z, y, x, MPFR_RNDN);
342  MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
343  /* 0+ -1 --> PI */
344  mpfr_set_si (x, -1, MPFR_RNDN);
345  mpfr_atan2 (z, y, x, MPFR_RNDN);
346  MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
347  /* 0- -1 --> -PI */
348  MPFR_CHANGE_SIGN (y);
349  mpfr_atan2 (z, y, x, MPFR_RNDN);
350  MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
351  /* 0- +1 --> 0- */
352  mpfr_set_ui (x, 1, MPFR_RNDN);
353  mpfr_atan2 (z, y, x, MPFR_RNDN);
354  MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
355  /* 0+ +1 --> 0+ */
356  MPFR_CHANGE_SIGN (y);
357  mpfr_atan2 (z, y, x, MPFR_RNDN);
358  MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
359  /* +1 0+ --> PI/2 */
360  mpfr_swap (x, y);
361  mpfr_atan2 (z, y, x, MPFR_RNDN);
362  MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
363  /* +1 0- --> PI/2 */
364  MPFR_CHANGE_SIGN (x);
365  mpfr_atan2 (z, y, x, MPFR_RNDN);
366  MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
367  /* -1 0- --> -PI/2 */
368  MPFR_CHANGE_SIGN (y);
369  mpfr_atan2 (z, y, x, MPFR_RNDN);
370  MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);
371  /* -1 0+ --> -PI/2 */
372  MPFR_CHANGE_SIGN (x);
373  mpfr_atan2 (z, y, x, MPFR_RNDN);
374  MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);
375
376  /* -1 +INF --> -0 */
377  MPFR_SET_INF (x);
378  mpfr_atan2 (z, y, x, MPFR_RNDN);
379  MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_NEG (z));
380  /* +1 +INF --> +0 */
381  MPFR_CHANGE_SIGN (y);
382  mpfr_atan2 (z, y, x, MPFR_RNDN);
383  MPFR_ASSERTN (MPFR_IS_ZERO (z) && MPFR_IS_POS (z));
384  /* +1 -INF --> +PI */
385  MPFR_CHANGE_SIGN (x);
386  mpfr_atan2 (z, y, x, MPFR_RNDN);
387  MPFR_ASSERTN (mpfr_cmp_str (z, "3.1415", 10, MPFR_RNDN) == 0);
388  /* -1 -INF --> -PI */
389  MPFR_CHANGE_SIGN (y);
390  mpfr_atan2 (z, y, x, MPFR_RNDN);
391  MPFR_ASSERTN (mpfr_cmp_str (z, "-3.1415", 10, MPFR_RNDN) == 0);
392  /* -INF -1 --> -PI/2 */
393  mpfr_swap (x, y);
394  mpfr_atan2 (z, y, x, MPFR_RNDN);
395  MPFR_ASSERTN (mpfr_cmp_str (z, "-1.57075", 10, MPFR_RNDN) == 0);
396  /* +INF -1  --> PI/2 */
397  MPFR_CHANGE_SIGN (y);
398  mpfr_atan2 (z, y, x, MPFR_RNDN);
399  MPFR_ASSERTN (mpfr_cmp_str (z, "1.57075", 10, MPFR_RNDN) == 0);
400  /* +INF -INF --> 3*PI/4 */
401  MPFR_SET_INF (x);
402  mpfr_atan2 (z, y, x, MPFR_RNDN);
403  MPFR_ASSERTN (mpfr_cmp_str (z, "2.356194490192344928", 10, MPFR_RNDN) == 0);
404  /* +INF +INF --> PI/4 */
405  MPFR_CHANGE_SIGN (x);
406  mpfr_atan2 (z, y, x, MPFR_RNDN);
407  MPFR_ASSERTN (mpfr_cmp_str (z, "0.785375", 10, MPFR_RNDN) == 0);
408  /* -INF +INF --> -PI/4 */
409  MPFR_CHANGE_SIGN (y);
410  mpfr_atan2 (z, y, x, MPFR_RNDN);
411  MPFR_ASSERTN (mpfr_cmp_str (z, "-0.785375", 10, MPFR_RNDN) == 0);
412  /* -INF -INF --> -3*PI/4 */
413  MPFR_CHANGE_SIGN (x);
414  mpfr_atan2 (z, y, x, MPFR_RNDN);
415  MPFR_ASSERTN (mpfr_cmp_str (z, "-2.356194490192344928", 10, MPFR_RNDN) == 0);
416  mpfr_set_prec (z, 905); /* exercises Ziv's loop */
417  mpfr_atan2 (z, y, x, MPFR_RNDZ);
418  MPFR_ASSERTN (mpfr_cmp_str (z, "-2.35619449019234492884698253745962716314787704953132936573120844423086230471465674897102611900658780098661106488496172998532038345716293667379401955609636083808771307702645389082916973346721171619778647332160823174945008459635673617534008737395340143185923642519259526145784", 10, MPFR_RNDN) == 0);
419
420  mpfr_clears (x, y, z, (mpfr_ptr) 0);
421}
422
423/* from Christopher Creutzig, 18 Jul 2007 */
424static void
425smallvals_atan2 (void)
426{
427  mpfr_t a, x, y;
428  mpfr_exp_t old_emin;
429
430  mpfr_inits (a, x, y, (mpfr_ptr) 0);
431  mpfr_set_ui (y, 0, MPFR_RNDN);
432  mpfr_nextbelow (y);
433  mpfr_set_ui (x, 1, MPFR_RNDN);
434  /* y=-2^(-emin-1), x=1 */
435
436  mpfr_atan2 (a, y, x, MPFR_RNDD);
437  MPFR_ASSERTN (mpfr_equal_p (a, y));
438
439  mpfr_atan2 (a, y, x, MPFR_RNDU);
440  MPFR_ASSERTN (mpfr_zero_p (a) && MPFR_IS_NEG(a));
441
442  mpfr_set_prec (x, 8);
443  mpfr_set_prec (y, 8);
444  mpfr_set_prec (a, 8);
445  old_emin = mpfr_get_emin ();
446  set_emin (MPFR_EMIN_MIN);
447
448  mpfr_set_si (y, 3, MPFR_RNDN);
449  mpfr_set_exp (y, mpfr_get_emin ());
450  mpfr_set_str_binary (x, "1.1");
451  mpfr_atan2 (a, y, x, MPFR_RNDU);
452  mpfr_set_si (y, 1, MPFR_RNDN);
453  mpfr_set_exp (y, mpfr_get_emin ());
454  MPFR_ASSERTN (mpfr_equal_p (a, y));
455
456  /* From a bug reported by Christopher Creutzig on 2007-08-28.
457     Added test in each rounding mode.
458     Segmentation fault or assertion failure due to an infinite Ziv loop. */
459  mpfr_set_si (y, 1, MPFR_RNDN);
460  mpfr_set_exp (y, mpfr_get_emin ());
461  mpfr_set_str_binary (x, "1.01");
462  mpfr_atan2 (a, y, x, MPFR_RNDZ);
463  MPFR_ASSERTN (mpfr_zero_p (a));
464  mpfr_atan2 (a, y, x, MPFR_RNDD);
465  MPFR_ASSERTN (mpfr_zero_p (a));
466  mpfr_atan2 (a, y, x, MPFR_RNDU);
467  MPFR_ASSERTN (mpfr_equal_p (a, y));
468  mpfr_atan2 (a, y, x, MPFR_RNDN);
469  MPFR_ASSERTN (mpfr_equal_p (a, y));
470
471  /* trigger underflow with rounding to nearest */
472  mpfr_set_ui (x, 4, MPFR_RNDN);
473  mpfr_atan2 (a, y, x, MPFR_RNDN);
474  MPFR_ASSERTN (mpfr_zero_p (a));
475
476  set_emin (old_emin);
477
478  mpfr_clears (a, x, y, (mpfr_ptr) 0);
479}
480
481/* Bug found by Robert Bajema (regression in MPFR 2.3.0).
482   The cause is the underflow flag set before the mpfr_atan2 call. */
483static void
484atan2_bug_20071003 (void)
485{
486  mpfr_t a, x, y, z;
487
488  mpfr_inits (a, x, y, z, (mpfr_ptr) 0);
489
490  mpfr_set_underflow ();
491  mpfr_set_str_binary (y,
492    "-0.10100110110100110111010110111111100110100010001110110E2");
493  mpfr_set_str_binary (x,
494    "0.10100101010110010100010010111000110110011110001011110E3");
495  mpfr_set_str_binary (z,
496    "-0.11101111001101101100111011001101000010010111101110110E-1");
497  mpfr_atan2 (a, y, x, MPFR_RNDN);
498  if (! mpfr_equal_p (a, z))
499    {
500      printf ("mpfr_atan2 fails on:\n");
501      printf ("  y = ");
502      mpfr_dump (y);
503      printf ("  x = ");
504      mpfr_dump (x);
505      printf ("Expected ");
506      mpfr_dump (z);
507      printf ("Got      ");
508      mpfr_dump (a);
509      exit (1);
510    }
511
512  mpfr_clears (a, x, y, z, (mpfr_ptr) 0);
513}
514
515/* Bug found on 2009-04-29 by Christopher Creutzig.
516 * With r6179: atan.c:62: MPFR assertion failed: r > n
517 */
518static void
519atan2_different_prec (void)
520{
521  mpfr_t a, x, y;
522
523  mpfr_init2 (a, 59);
524  mpfr_init2 (x, 59);
525  mpfr_init2 (y, 86);
526
527  mpfr_set_ui (x, 1, MPFR_RNDN);
528  mpfr_set_ui (y, 1, MPFR_RNDN);
529  mpfr_nextbelow (y);
530  mpfr_atan2 (a, y, x, MPFR_RNDN);
531
532  mpfr_clears (a, x, y, (mpfr_ptr) 0);
533}
534
535static void
536atan2_pow_of_2 (void)
537{
538  mpfr_t x, y, r, g;
539  int i;
540  int d[] = { 0, -1, 1 };
541  int ntests = numberof (d);
542
543  mpfr_init2 (x, 53);
544  mpfr_init2 (y, 53);
545  mpfr_init2 (r, 53);
546  mpfr_init2 (g, 53);
547
548  /* atan(42) */
549  mpfr_set_str_binary (g, "1100011000000011110011111001100110101000011010010011E-51");
550
551  for (i = 0; i < ntests; ++i)
552    {
553      mpfr_set_ui (y, 42, MPFR_RNDN);
554      mpfr_mul_2si (y, y, d[i], MPFR_RNDN);
555      mpfr_set_ui_2exp (x, 1, d[i], MPFR_RNDN);
556      mpfr_atan2 (r, y, x, MPFR_RNDN);
557      if (mpfr_equal_p (r, g) == 0)
558        {
559          printf ("Error in mpfr_atan2 (5)\n");
560          printf ("Expected "); mpfr_dump (g);
561          printf ("Got      "); mpfr_dump (r);
562          exit (1);
563        }
564    }
565  mpfr_clear (x);
566  mpfr_clear (y);
567  mpfr_clear (r);
568  mpfr_clear (g);
569}
570
571/* https://sympa.inria.fr/sympa/arc/mpfr/2011-05/msg00008.html
572 * Incorrect flags (in debug mode on a 32-bit machine, assertion failure).
573 */
574static void
575reduced_expo_range (void)
576{
577  mpfr_exp_t emin, emax;
578  mpfr_t x, y, ex_y;
579  int inex, ex_inex;
580  unsigned int flags, ex_flags;
581
582  emin = mpfr_get_emin ();
583  emax = mpfr_get_emax ();
584
585  mpfr_inits2 (12, x, y, ex_y, (mpfr_ptr) 0);
586  mpfr_set_str (x, "0.1e-5", 2, MPFR_RNDN);
587
588  set_emin (-5);
589  set_emax (-5);
590  mpfr_clear_flags ();
591  inex = mpfr_atan (y, x, MPFR_RNDN);
592  flags = __gmpfr_flags;
593  set_emin (emin);
594  set_emax (emax);
595
596  mpfr_set_str (ex_y, "0.1e-5", 2, MPFR_RNDN);
597  ex_inex = 1;
598  ex_flags = MPFR_FLAGS_INEXACT;
599
600  if (VSIGN (inex) != ex_inex || flags != ex_flags ||
601      ! mpfr_equal_p (y, ex_y))
602    {
603      printf ("Error in reduced_expo_range\non x = ");
604      mpfr_dump (x);
605      printf ("Expected y = ");
606      mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN);
607      printf ("\n         inex = %d, flags = %u\n", ex_inex, ex_flags);
608      printf ("Got      y = ");
609      mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
610      printf ("\n         inex = %d, flags = %u\n", VSIGN (inex), flags);
611      exit (1);
612    }
613
614  mpfr_clears (x, y, ex_y, (mpfr_ptr) 0);
615}
616
617int
618main (int argc, char *argv[])
619{
620  tests_start_mpfr ();
621
622  special_overflow ();
623  special ();
624  special_atan2 ();
625  smallvals_atan2 ();
626  atan2_bug_20071003 ();
627  atan2_different_prec ();
628  reduced_expo_range ();
629
630  test_generic_atan  (MPFR_PREC_MIN, 200, 17);
631  test_generic_atan2 (MPFR_PREC_MIN, 200, 17);
632  test_generic_atan2_neg (MPFR_PREC_MIN, 200, 17);
633
634  data_check ("data/atan", mpfr_atan, "mpfr_atan");
635  bad_cases (mpfr_atan, mpfr_tan, "mpfr_atan", 256, -40, 1, 4, 128, 800, 40);
636  atan2_pow_of_2 ();
637
638  tests_end_mpfr ();
639  return 0;
640}
641