1 /* Test file for mpfr_asin.
2
3 Copyright 2001-2023 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramba 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 https://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 "mpfr-test.h"
24
25 #define TEST_FUNCTION mpfr_asin
26 #define TEST_RANDOM_EMAX 7
27 #include "tgeneric.c"
28
29 static void
special(void)30 special (void)
31 {
32 mpfr_t x, y;
33 int r;
34
35 mpfr_init (x);
36 mpfr_init (y);
37
38 /* asin(NaN) = NaN */
39 mpfr_set_nan (x);
40 mpfr_asin (y, x, MPFR_RNDN);
41 if (!mpfr_nan_p (y))
42 {
43 printf ("Error: mpfr_asin (NaN) <> NaN\n");
44 exit (1);
45 }
46
47 /* asin(+/-Inf) = NaN */
48 mpfr_set_inf (x, 1);
49 mpfr_asin (y, x, MPFR_RNDN);
50 if (!mpfr_nan_p (y))
51 {
52 printf ("Error: mpfr_asin (+Inf) <> NaN\n");
53 exit (1);
54 }
55 mpfr_set_inf (x, -1);
56 mpfr_asin (y, x, MPFR_RNDN);
57 if (!mpfr_nan_p (y))
58 {
59 printf ("Error: mpfr_asin (-Inf) <> NaN\n");
60 exit (1);
61 }
62
63 /* asin(+/-2) = NaN */
64 mpfr_set_ui (x, 2, MPFR_RNDN);
65 mpfr_asin (y, x, MPFR_RNDN);
66 if (!mpfr_nan_p (y))
67 {
68 printf ("Error: mpfr_asin (+2) <> NaN\n");
69 exit (1);
70 }
71 mpfr_set_si (x, -2, MPFR_RNDN);
72 mpfr_asin (y, x, MPFR_RNDN);
73 if (!mpfr_nan_p (y))
74 {
75 printf ("Error: mpfr_asin (-2) <> NaN\n");
76 exit (1);
77 }
78
79 /* asin(+/-0) = +/-0 */
80 mpfr_set_ui (x, 0, MPFR_RNDN);
81 mpfr_asin (y, x, MPFR_RNDN);
82 if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
83 {
84 printf ("Error: mpfr_asin (+0) <> +0\n");
85 exit (1);
86 }
87 mpfr_neg (x, x, MPFR_RNDN);
88 mpfr_asin (y, x, MPFR_RNDN);
89 if (MPFR_NOTZERO (y) || MPFR_IS_POS (y))
90 {
91 printf ("Error: mpfr_asin (-0) <> -0\n");
92 exit (1);
93 }
94
95 /* asin(1) = Pi/2 */
96 RND_LOOP (r)
97 {
98 mpfr_set_ui (x, 1, MPFR_RNDN); /* exact */
99 mpfr_asin (y, x, (mpfr_rnd_t) r);
100 mpfr_const_pi (x, (mpfr_rnd_t) r);
101 mpfr_div_2ui (x, x, 1, MPFR_RNDN); /* exact */
102 if (mpfr_cmp (x, y))
103 {
104 printf ("Error: asin(1) != Pi/2 for rnd=%s\n",
105 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
106 exit (1);
107 }
108 }
109
110 /* asin(-1) = -Pi/2 */
111 RND_LOOP (r)
112 {
113 mpfr_set_si (x, -1, MPFR_RNDN); /* exact */
114 mpfr_asin (y, x, (mpfr_rnd_t) r);
115 mpfr_const_pi (x, MPFR_INVERT_RND((mpfr_rnd_t) r));
116 mpfr_neg (x, x, MPFR_RNDN); /* exact */
117 mpfr_div_2ui (x, x, 1, MPFR_RNDN); /* exact */
118 if (mpfr_cmp (x, y))
119 {
120 printf ("Error: asin(-1) != -Pi/2 for rnd=%s\n",
121 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
122 exit (1);
123 }
124 }
125
126 mpfr_set_prec (x, 32);
127 mpfr_set_prec (y, 32);
128
129 mpfr_set_str_binary (x, "0.1101110111111111001011101000101");
130 mpfr_asin (x, x, MPFR_RNDN);
131 mpfr_set_str_binary (y, "1.00001100101011000001111100111");
132 if (mpfr_cmp (x, y))
133 {
134 printf ("Error: mpfr_asin (1)\n");
135 exit (1);
136 }
137
138 mpfr_set_str_binary (x, "-0.01110111000011101010111100000101");
139 mpfr_asin (x, x, MPFR_RNDN);
140 mpfr_set_str_binary (y, "-0.0111101111010100011111110101");
141 if (mpfr_cmp (x, y))
142 {
143 printf ("Error: mpfr_asin (2)\n");
144 mpfr_dump (x);
145 mpfr_dump (y);
146 exit (1);
147 }
148
149 mpfr_set_prec (x, 9);
150 mpfr_set_prec (y, 19);
151 mpfr_set_str_binary (x, "0.110000000E-6");
152 mpfr_asin (y, x, MPFR_RNDD);
153 mpfr_set_prec (x, 19);
154 mpfr_set_str_binary (x, "0.1100000000000001001E-6");
155 if (mpfr_cmp (x, y))
156 {
157 printf ("Error: mpfr_asin (3)\n");
158 mpfr_dump (x);
159 mpfr_dump (y);
160 exit (1);
161 }
162
163 mpfr_clear (x);
164 mpfr_clear (y);
165 }
166
167 static void
special_overflow(void)168 special_overflow (void)
169 {
170 mpfr_t x, y;
171 mpfr_exp_t emin, emax;
172
173 emin = mpfr_get_emin ();
174 emax = mpfr_get_emax ();
175
176 set_emin (-125);
177 set_emax (128);
178 mpfr_init2 (x, 24);
179 mpfr_init2 (y, 48);
180 mpfr_set_str_binary (x, "0.101100100000000000110100E0");
181 mpfr_asin (y, x, MPFR_RNDN);
182 if (mpfr_cmp_str (y, "0.110001001101001111110000010110001000111011001000E0",
183 2, MPFR_RNDN))
184 {
185 printf("Special Overflow error.\n");
186 mpfr_dump (y);
187 exit (1);
188 }
189 mpfr_clear (y);
190 mpfr_clear (x);
191 set_emin (emin);
192 set_emax (emax);
193 }
194
195 /* bug reported by Kevin Rauch on 15 December 2007 */
196 static void
test20071215(void)197 test20071215 (void)
198 {
199 mpfr_t x, y;
200
201 mpfr_init (x);
202 mpfr_init (y);
203
204 mpfr_set_ui (x, 0, MPFR_RNDN);
205 mpfr_neg (x, x, MPFR_RNDN);
206 mpfr_set_ui (y, 1, MPFR_RNDN);
207 mpfr_asin (y, x, MPFR_RNDN);
208 MPFR_ASSERTN(mpfr_zero_p (y) && MPFR_IS_NEG(y));
209
210 mpfr_set_ui (x, 0, MPFR_RNDN);
211 mpfr_set_si (y, -1, MPFR_RNDN);
212 mpfr_asin (y, x, MPFR_RNDN);
213 MPFR_ASSERTN(mpfr_zero_p (y) && MPFR_IS_POS(y));
214
215 mpfr_clear (x);
216 mpfr_clear (y);
217 }
218
219 static void
reduced_expo_range(void)220 reduced_expo_range (void)
221 {
222 mpfr_exp_t emin, emax;
223 mpfr_t x, y, ex_y;
224 int inex, ex_inex;
225 unsigned int flags, ex_flags;
226
227 emin = mpfr_get_emin ();
228 emax = mpfr_get_emax ();
229
230 mpfr_inits2 (4, x, y, ex_y, (mpfr_ptr) 0);
231 mpfr_set_str (x, "-0.1e1", 2, MPFR_RNDN);
232
233 set_emin (1);
234 set_emax (1);
235 mpfr_clear_flags ();
236 inex = mpfr_asin (y, x, MPFR_RNDA);
237 flags = __gmpfr_flags;
238 set_emin (emin);
239 set_emax (emax);
240
241 mpfr_set_str (ex_y, "-0.1101e1", 2, MPFR_RNDN);
242 ex_inex = -1;
243 ex_flags = MPFR_FLAGS_INEXACT;
244
245 if (VSIGN (inex) != ex_inex || flags != ex_flags ||
246 ! mpfr_equal_p (y, ex_y))
247 {
248 printf ("Error in reduced_expo_range\non x = ");
249 mpfr_dump (x);
250 printf ("Expected y = ");
251 mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN);
252 printf ("\n inex = %d, flags = %u\n", ex_inex, ex_flags);
253 printf ("Got y = ");
254 mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
255 printf ("\n inex = %d, flags = %u\n", VSIGN (inex), flags);
256 exit (1);
257 }
258
259 mpfr_clears (x, y, ex_y, (mpfr_ptr) 0);
260 }
261
262 int
main(void)263 main (void)
264 {
265 tests_start_mpfr ();
266
267 special ();
268 special_overflow ();
269 reduced_expo_range ();
270
271 test_generic (MPFR_PREC_MIN, 100, 15);
272
273 tests_end_mpfr ();
274
275 data_check ("data/asin", mpfr_asin, "mpfr_asin");
276 bad_cases (mpfr_asin, mpfr_sin, "mpfr_asin", 256, -40, 1, 4, 128, 800, 30);
277
278 test20071215 ();
279
280 tests_end_mpfr ();
281 return 0;
282 }
283