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