1/* Test file for mpfr_asinu.
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_asinu
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  /* asinu(x,1) = asin(x)/(2*pi) will underflow */
41  mpfr_asinu (y, x, 1, MPFR_RNDN);
42  MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
43  mpfr_asinu (y, x, 1, MPFR_RNDZ);
44  MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
45  mpfr_asinu (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_asinu (y, x, 1, MPFR_RNDN);
70  if (mpfr_nan_p (y) == 0)
71    {
72      printf ("Error: asinu (NaN, 1) != NaN\n");
73      exit (1);
74    }
75
76  mpfr_set_inf (x, 1);
77  mpfr_asinu (y, x, 1, MPFR_RNDN);
78  if (mpfr_nan_p (y) == 0)
79    {
80      printf ("Error: asinu (+Inf, 1) != NaN\n");
81      exit (1);
82    }
83
84  mpfr_set_inf (x, -1);
85  mpfr_asinu (y, x, 1, MPFR_RNDN);
86  if (mpfr_nan_p (y) == 0)
87    {
88      printf ("Error: asinu (-Inf, 1) != NaN\n");
89      exit (1);
90    }
91
92  /* asinu (+0,u) = +0 */
93  mpfr_set_ui (x, 0, MPFR_RNDN);
94  mpfr_asinu (y, x, 1, MPFR_RNDN);
95  if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
96    {
97      printf ("Error: asinu(+0,1) != +0\n");
98      exit (1);
99    }
100
101  /* asinu (-0,u) = -0 */
102  mpfr_set_ui (x, 0, MPFR_RNDN);
103  mpfr_neg (x, x, MPFR_RNDN);
104  mpfr_asinu (y, x, 1, MPFR_RNDN);
105  if (MPFR_NOTZERO (y) || MPFR_IS_POS (y))
106    {
107      printf ("Error: asinu(-0,1) != -0\n");
108      exit (1);
109    }
110
111  /* tests for |x| > 1 */
112  mpfr_set_ui (x, 2, MPFR_RNDN);
113  mpfr_asinu (y, x, 1, MPFR_RNDN);
114  if (mpfr_nan_p (y) == 0)
115    {
116      printf ("Error: asinu (2, 1) != NaN\n");
117      exit (1);
118    }
119
120  mpfr_set_si (x, -2, MPFR_RNDN);
121  mpfr_asinu (y, x, 1, MPFR_RNDN);
122  if (mpfr_nan_p (y) == 0)
123    {
124      printf ("Error: asinu (-2, 1) != NaN\n");
125      exit (1);
126    }
127
128  mpfr_set_ui (x, 2, MPFR_RNDN);
129  mpfr_asinu (y, x, 0, MPFR_RNDN);
130  if (mpfr_nan_p (y) == 0)
131    {
132      printf ("Error: asinu (2, 0) != NaN\n");
133      exit (1);
134    }
135
136  mpfr_set_si (x, -2, MPFR_RNDN);
137  mpfr_asinu (y, x, 0, MPFR_RNDN);
138  if (mpfr_nan_p (y) == 0)
139    {
140      printf ("Error: asinu (-2, 0) != NaN\n");
141      exit (1);
142    }
143
144  /* asinu (1,u) = u/4 */
145  RND_LOOP (r)
146    {
147      mpfr_set_si (x, 1, MPFR_RNDN); /* exact */
148      mpfr_asinu (y, x, 17, (mpfr_rnd_t) r);
149      mpfr_set_ui_2exp (x, 17, -2, (mpfr_rnd_t) r);
150      if (!mpfr_equal_p (x, y))
151        {
152          printf ("Error: asinu(1,17) != 17/4 for rnd=%s\n",
153                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
154          exit (1);
155        }
156    }
157
158  /* asinu (-1,u) = -u/4 */
159  RND_LOOP (r)
160    {
161      mpfr_set_si (x, -1, MPFR_RNDN); /* exact */
162      mpfr_asinu (y, x, 17, (mpfr_rnd_t) r);
163      mpfr_set_si_2exp (x, -17, -2, (mpfr_rnd_t) r);
164      if (!mpfr_equal_p (x, y))
165        {
166          printf ("Error: asinu(-1,17) != -17/4 for rnd=%s\n",
167                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
168          exit (1);
169        }
170    }
171
172  /* asinu (1/2,u) = u/12 */
173  for (u = 1; u < 100; u++)
174     RND_LOOP (r)
175       {
176         mpfr_set_ui_2exp (x, 1, -1, MPFR_RNDN); /* exact */
177         mpfr_asinu (y, x, u, (mpfr_rnd_t) r);
178         inex = mpfr_set_ui (x, u, MPFR_RNDN);
179         MPFR_ASSERTN(inex == 0);
180         inex = mpfr_div_ui (x, x, 12, (mpfr_rnd_t) r);
181         if ((r != MPFR_RNDF || inex == 0) && !mpfr_equal_p (x, y))
182           {
183             printf ("Error: asinu(1/2,u) != u/12 for u=%lu and rnd=%s\n",
184                     u, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
185             printf ("got: "); mpfr_dump (y);
186             exit (1);
187           }
188       }
189
190  /* asinu (-1/2,u) = -u/12 */
191  for (u = 1; u < 100; u++)
192     RND_LOOP (r)
193       {
194         mpfr_set_si_2exp (x, -1, -1, MPFR_RNDN); /* exact */
195         mpfr_asinu (y, x, u, (mpfr_rnd_t) r);
196         inex = mpfr_set_ui (x, u, MPFR_RNDN);
197         MPFR_ASSERTN(inex == 0);
198         inex = mpfr_div_si (x, x, -12, (mpfr_rnd_t) r);
199         if ((r != MPFR_RNDF || inex == 0) && !mpfr_equal_p (x, y))
200           {
201             printf ("Error: asinu(-1/2,u) != -u/12 for u=%lu and rnd=%s\n",
202                     u, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
203             printf ("expected: "); mpfr_dump (x);
204             printf ("got:      "); mpfr_dump (y);
205             exit (1);
206           }
207       }
208
209  test_generic (MPFR_PREC_MIN, 100, 100);
210
211  mpfr_clear (x);
212  mpfr_clear (y);
213
214  tests_end_mpfr ();
215  return 0;
216}
217