1275970Scy/* Test file for mpfr_asinu.
2275970Scy
3275970ScyCopyright 2021-2023 Free Software Foundation, Inc.
4275970ScyContributed by the AriC and Caramba projects, INRIA.
5275970Scy
6275970ScyThis file is part of the GNU MPFR Library.
7275970Scy
8275970ScyThe GNU MPFR Library is free software; you can redistribute it and/or modify
9275970Scyit under the terms of the GNU Lesser General Public License as published by
10275970Scythe Free Software Foundation; either version 3 of the License, or (at your
11275970Scyoption) any later version.
12275970Scy
13275970ScyThe GNU MPFR Library is distributed in the hope that it will be useful, but
14275970ScyWITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15275970Scyor FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16275970ScyLicense for more details.
17275970Scy
18275970ScyYou should have received a copy of the GNU Lesser General Public License
19275970Scyalong with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20275970Scyhttps://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21275970Scy51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22275970Scy
23275970Scy#include "mpfr-test.h"
24275970Scy
25275970Scy#define TEST_FUNCTION mpfr_asinu
26275970Scy#define ULONG_ARG2
27275970Scy#include "tgeneric.c"
28275970Scy
29275970Scystatic void
30275970Scycheck_underflow (void)
31275970Scy{
32275970Scy  mpfr_t x, y;
33275970Scy  mpfr_exp_t emin = mpfr_get_emin ();
34275970Scy
35275970Scy  set_emin (mpfr_get_emin_min ());
36275970Scy
37275970Scy  mpfr_init2 (x, MPFR_PREC_MIN);
38275970Scy  mpfr_init2 (y, MPFR_PREC_MIN);
39330567Sgordon  mpfr_set_ui_2exp (x, 1, mpfr_get_emin_min () - 1, MPFR_RNDN);
40275970Scy  /* asinu(x,1) = asin(x)/(2*pi) will underflow */
41275970Scy  mpfr_asinu (y, x, 1, MPFR_RNDN);
42275970Scy  MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
43275970Scy  mpfr_asinu (y, x, 1, MPFR_RNDZ);
44275970Scy  MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
45275970Scy  mpfr_asinu (y, x, 1, MPFR_RNDU);
46275970Scy  MPFR_ASSERTN(mpfr_cmp_ui_2exp (y, 1, mpfr_get_emin_min () - 1) == 0);
47275970Scy  mpfr_clear (x);
48275970Scy  mpfr_clear (y);
49275970Scy
50275970Scy  set_emin (emin);
51275970Scy}
52275970Scy
53275970Scyint
54275970Scymain (void)
55275970Scy{
56275970Scy  mpfr_t x, y;
57275970Scy  int r, inex;
58275970Scy  unsigned long u;
59275970Scy
60275970Scy  tests_start_mpfr ();
61275970Scy
62275970Scy  check_underflow ();
63275970Scy
64275970Scy  mpfr_init (x);
65275970Scy  mpfr_init (y);
66275970Scy
67275970Scy  /* check singular cases */
68275970Scy  MPFR_SET_NAN(x);
69275970Scy  mpfr_asinu (y, x, 1, MPFR_RNDN);
70275970Scy  if (mpfr_nan_p (y) == 0)
71275970Scy    {
72275970Scy      printf ("Error: asinu (NaN, 1) != NaN\n");
73275970Scy      exit (1);
74275970Scy    }
75275970Scy
76275970Scy  mpfr_set_inf (x, 1);
77275970Scy  mpfr_asinu (y, x, 1, MPFR_RNDN);
78275970Scy  if (mpfr_nan_p (y) == 0)
79275970Scy    {
80275970Scy      printf ("Error: asinu (+Inf, 1) != NaN\n");
81275970Scy      exit (1);
82275970Scy    }
83275970Scy
84275970Scy  mpfr_set_inf (x, -1);
85275970Scy  mpfr_asinu (y, x, 1, MPFR_RNDN);
86275970Scy  if (mpfr_nan_p (y) == 0)
87275970Scy    {
88275970Scy      printf ("Error: asinu (-Inf, 1) != NaN\n");
89275970Scy      exit (1);
90275970Scy    }
91275970Scy
92275970Scy  /* asinu (+0,u) = +0 */
93275970Scy  mpfr_set_ui (x, 0, MPFR_RNDN);
94275970Scy  mpfr_asinu (y, x, 1, MPFR_RNDN);
95275970Scy  if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
96275970Scy    {
97275970Scy      printf ("Error: asinu(+0,1) != +0\n");
98275970Scy      exit (1);
99275970Scy    }
100275970Scy
101275970Scy  /* asinu (-0,u) = -0 */
102275970Scy  mpfr_set_ui (x, 0, MPFR_RNDN);
103275970Scy  mpfr_neg (x, x, MPFR_RNDN);
104275970Scy  mpfr_asinu (y, x, 1, MPFR_RNDN);
105275970Scy  if (MPFR_NOTZERO (y) || MPFR_IS_POS (y))
106275970Scy    {
107275970Scy      printf ("Error: asinu(-0,1) != -0\n");
108275970Scy      exit (1);
109275970Scy    }
110275970Scy
111275970Scy  /* tests for |x| > 1 */
112275970Scy  mpfr_set_ui (x, 2, MPFR_RNDN);
113275970Scy  mpfr_asinu (y, x, 1, MPFR_RNDN);
114275970Scy  if (mpfr_nan_p (y) == 0)
115275970Scy    {
116275970Scy      printf ("Error: asinu (2, 1) != NaN\n");
117275970Scy      exit (1);
118275970Scy    }
119275970Scy
120275970Scy  mpfr_set_si (x, -2, MPFR_RNDN);
121275970Scy  mpfr_asinu (y, x, 1, MPFR_RNDN);
122275970Scy  if (mpfr_nan_p (y) == 0)
123275970Scy    {
124275970Scy      printf ("Error: asinu (-2, 1) != NaN\n");
125275970Scy      exit (1);
126275970Scy    }
127275970Scy
128275970Scy  mpfr_set_ui (x, 2, MPFR_RNDN);
129275970Scy  mpfr_asinu (y, x, 0, MPFR_RNDN);
130275970Scy  if (mpfr_nan_p (y) == 0)
131275970Scy    {
132275970Scy      printf ("Error: asinu (2, 0) != NaN\n");
133275970Scy      exit (1);
134275970Scy    }
135275970Scy
136275970Scy  mpfr_set_si (x, -2, MPFR_RNDN);
137275970Scy  mpfr_asinu (y, x, 0, MPFR_RNDN);
138275970Scy  if (mpfr_nan_p (y) == 0)
139275970Scy    {
140275970Scy      printf ("Error: asinu (-2, 0) != NaN\n");
141275970Scy      exit (1);
142275970Scy    }
143275970Scy
144275970Scy  /* asinu (1,u) = u/4 */
145275970Scy  RND_LOOP (r)
146275970Scy    {
147275970Scy      mpfr_set_si (x, 1, MPFR_RNDN); /* exact */
148275970Scy      mpfr_asinu (y, x, 17, (mpfr_rnd_t) r);
149275970Scy      mpfr_set_ui_2exp (x, 17, -2, (mpfr_rnd_t) r);
150275970Scy      if (!mpfr_equal_p (x, y))
151275970Scy        {
152275970Scy          printf ("Error: asinu(1,17) != 17/4 for rnd=%s\n",
153275970Scy                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
154275970Scy          exit (1);
155330567Sgordon        }
156275970Scy    }
157275970Scy
158275970Scy  /* asinu (-1,u) = -u/4 */
159275970Scy  RND_LOOP (r)
160275970Scy    {
161275970Scy      mpfr_set_si (x, -1, MPFR_RNDN); /* exact */
162275970Scy      mpfr_asinu (y, x, 17, (mpfr_rnd_t) r);
163275970Scy      mpfr_set_si_2exp (x, -17, -2, (mpfr_rnd_t) r);
164275970Scy      if (!mpfr_equal_p (x, y))
165275970Scy        {
166275970Scy          printf ("Error: asinu(-1,17) != -17/4 for rnd=%s\n",
167275970Scy                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
168275970Scy          exit (1);
169275970Scy        }
170275970Scy    }
171275970Scy
172275970Scy  /* asinu (1/2,u) = u/12 */
173275970Scy  for (u = 1; u < 100; u++)
174275970Scy     RND_LOOP (r)
175275970Scy       {
176275970Scy         mpfr_set_ui_2exp (x, 1, -1, MPFR_RNDN); /* exact */
177275970Scy         mpfr_asinu (y, x, u, (mpfr_rnd_t) r);
178275970Scy         inex = mpfr_set_ui (x, u, MPFR_RNDN);
179275970Scy         MPFR_ASSERTN(inex == 0);
180275970Scy         inex = mpfr_div_ui (x, x, 12, (mpfr_rnd_t) r);
181275970Scy         if ((r != MPFR_RNDF || inex == 0) && !mpfr_equal_p (x, y))
182275970Scy           {
183275970Scy             printf ("Error: asinu(1/2,u) != u/12 for u=%lu and rnd=%s\n",
184275970Scy                     u, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
185275970Scy             printf ("got: "); mpfr_dump (y);
186275970Scy             exit (1);
187275970Scy           }
188275970Scy       }
189275970Scy
190275970Scy  /* asinu (-1/2,u) = -u/12 */
191275970Scy  for (u = 1; u < 100; u++)
192275970Scy     RND_LOOP (r)
193275970Scy       {
194275970Scy         mpfr_set_si_2exp (x, -1, -1, MPFR_RNDN); /* exact */
195275970Scy         mpfr_asinu (y, x, u, (mpfr_rnd_t) r);
196275970Scy         inex = mpfr_set_ui (x, u, MPFR_RNDN);
197275970Scy         MPFR_ASSERTN(inex == 0);
198275970Scy         inex = mpfr_div_si (x, x, -12, (mpfr_rnd_t) r);
199275970Scy         if ((r != MPFR_RNDF || inex == 0) && !mpfr_equal_p (x, y))
200275970Scy           {
201275970Scy             printf ("Error: asinu(-1/2,u) != -u/12 for u=%lu and rnd=%s\n",
202275970Scy                     u, mpfr_print_rnd_mode ((mpfr_rnd_t) r));
203275970Scy             printf ("expected: "); mpfr_dump (x);
204275970Scy             printf ("got:      "); mpfr_dump (y);
205275970Scy             exit (1);
206275970Scy           }
207275970Scy       }
208275970Scy
209275970Scy  test_generic (MPFR_PREC_MIN, 100, 100);
210275970Scy
211275970Scy  mpfr_clear (x);
212275970Scy  mpfr_clear (y);
213275970Scy
214275970Scy  tests_end_mpfr ();
215275970Scy  return 0;
216275970Scy}
217275970Scy