xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tasin.c (revision 17dc1ceb5c5ff563444a48bf21025d7ddee5f8d2)
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