1/* Test file for mpfr_atanu.
2
3Copyright 2021-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
25#define TEST_FUNCTION mpfr_atanu
26#define ULONG_ARG2
27#include "tgeneric.c"
28
29static void
30check_underflow (void)
31{
32  mpfr_t x, y;
33  mpfr_exp_t emin = mpfr_get_emin ();
34
35  set_emin (mpfr_get_emin_min ());
36
37  mpfr_init2 (x, MPFR_PREC_MIN);
38  mpfr_init2 (y, MPFR_PREC_MIN);
39  mpfr_set_ui_2exp (x, 1, mpfr_get_emin_min () - 1, MPFR_RNDN);
40  /* atanu(x,1) = atan(x)/(2*pi) will underflow */
41  mpfr_atanu (y, x, 1, MPFR_RNDN);
42  MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
43  mpfr_atanu (y, x, 1, MPFR_RNDZ);
44  MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
45  mpfr_atanu (y, x, 1, MPFR_RNDU);
46  MPFR_ASSERTN(mpfr_cmp_ui_2exp (y, 1, mpfr_get_emin_min () - 1) == 0);
47  mpfr_clear (x);
48  mpfr_clear (y);
49
50  set_emin (emin);
51}
52
53int
54main (void)
55{
56  mpfr_t x, y;
57  int r, inex;
58  unsigned long u;
59
60  tests_start_mpfr ();
61
62  check_underflow ();
63
64  mpfr_init (x);
65  mpfr_init (y);
66
67  /* check singular cases */
68  MPFR_SET_NAN(x);
69  mpfr_atanu (y, x, 1, MPFR_RNDN);
70  if (mpfr_nan_p (y) == 0)
71    {
72      printf ("Error: atanu (NaN, 1) != NaN\n");
73      exit (1);
74    }
75
76  mpfr_set_inf (x, 1);
77  mpfr_atanu (y, x, 1, MPFR_RNDN);
78  if (mpfr_cmp_ui_2exp (y, 1, -2) != 0)
79    {
80      printf ("Error: atanu (+Inf, 1) != 1/4\n");
81      printf ("got: "); mpfr_dump (y);
82      exit (1);
83    }
84
85  mpfr_set_inf (x, -1);
86  mpfr_atanu (y, x, 1, MPFR_RNDN);
87  if (mpfr_cmp_si_2exp (y, -1, -2) != 0)
88    {
89      printf ("Error: atanu (-Inf, 1) != -1/4\n");
90      exit (1);
91    }
92
93  /* atanu (+0,u) = +0 */
94  mpfr_set_ui (x, 0, MPFR_RNDN);
95  mpfr_atanu (y, x, 1, MPFR_RNDN);
96  if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
97    {
98      printf ("Error: atanu(+0,1) != +0\n");
99      exit (1);
100    }
101
102  /* atanu (-0,u) = -0 */
103  mpfr_set_ui (x, 0, MPFR_RNDN);
104  mpfr_neg (x, x, MPFR_RNDN);
105  mpfr_atanu (y, x, 1, MPFR_RNDN);
106  if (MPFR_NOTZERO (y) || MPFR_IS_POS (y))
107    {
108      printf ("Error: atanu(-0,1) != -0\n");
109      exit (1);
110    }
111
112  /* atanu (1,u) = u/8 */
113  for (u = 1; u < 100; u++)
114     RND_LOOP (r)
115       {
116         mpfr_set_ui (x, 1, MPFR_RNDN); /* exact */
117         mpfr_atanu (y, x, u, (mpfr_rnd_t) r);
118         inex = mpfr_set_ui (x, u, MPFR_RNDN);
119         MPFR_ASSERTN(inex == 0);
120         inex = mpfr_div_ui (x, x, 8, (mpfr_rnd_t) r);
121         if ((r != MPFR_RNDF || inex == 0) && !mpfr_equal_p (x, y))
122           {
123             printf ("Error: atanu(1,u) != u/8 for u=%lu and rnd=%s\n",
124                     u, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
125             printf ("got: "); mpfr_dump (y);
126             exit (1);
127           }
128       }
129
130  /* atanu (-1,u) = -u/8 */
131  for (u = 1; u < 100; u++)
132     RND_LOOP (r)
133       {
134         mpfr_set_si (x, -1, MPFR_RNDN); /* exact */
135         mpfr_atanu (y, x, u, (mpfr_rnd_t) r);
136         inex = mpfr_set_ui (x, u, MPFR_RNDN);
137         MPFR_ASSERTN(inex == 0);
138         inex = mpfr_div_si (x, x, -8, (mpfr_rnd_t) r);
139         if ((r != MPFR_RNDF || inex == 0) && !mpfr_equal_p (x, y))
140           {
141             printf ("Error: atanu(-1,u) != -u/8 for u=%lu and rnd=%s\n",
142                     u, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
143             printf ("got: "); mpfr_dump (y);
144             exit (1);
145           }
146       }
147
148  /* case u=0 */
149  mpfr_set_ui (x, 1, MPFR_RNDN);
150  mpfr_atanu (y, x, 0, MPFR_RNDN);
151  if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
152    {
153      printf ("Error: atanu(1,0) != +0\n");
154      printf ("got "); mpfr_dump (y);
155      exit (1);
156    }
157  mpfr_set_si (x, -1, MPFR_RNDN);
158  mpfr_atanu (y, x, 0, MPFR_RNDN);
159  if (MPFR_NOTZERO (y) || MPFR_IS_POS (y))
160    {
161      printf ("Error: atanu(-1,0) != -0\n");
162      printf ("got "); mpfr_dump (y);
163      exit (1);
164    }
165
166  test_generic (MPFR_PREC_MIN, 100, 100);
167
168  mpfr_clear (x);
169  mpfr_clear (y);
170
171  tests_end_mpfr ();
172  return 0;
173}
174