xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/ttanu.c (revision ba125506a622fe649968631a56eba5d42ff57863)
1 /* Test file for mpfr_tanu.
2 
3 Copyright 2020-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 static void
test_singular(void)26 test_singular (void)
27 {
28   mpfr_t x, y;
29   int inexact;
30 
31   mpfr_init (x);
32   mpfr_init (y);
33 
34   /* check u = 0 */
35   mpfr_set_ui (x, 17, MPFR_RNDN);
36   inexact = mpfr_tanu (y, x, 0, MPFR_RNDN);
37   MPFR_ASSERTN(mpfr_nan_p (y));
38 
39   /* check x = NaN */
40   mpfr_set_nan (x);
41   inexact = mpfr_tanu (y, x, 1, MPFR_RNDN);
42   MPFR_ASSERTN(mpfr_nan_p (y));
43 
44   /* check x = +Inf */
45   mpfr_set_inf (x, 1);
46   inexact = mpfr_tanu (y, x, 1, MPFR_RNDN);
47   MPFR_ASSERTN(mpfr_nan_p (y));
48 
49   /* check x = -Inf */
50   mpfr_set_inf (x, -1);
51   inexact = mpfr_tanu (y, x, 1, MPFR_RNDN);
52   MPFR_ASSERTN(mpfr_nan_p (y));
53 
54   /* check x = +0 */
55   mpfr_set_zero (x, 1);
56   inexact = mpfr_tanu (y, x, 1, MPFR_RNDN);
57   MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
58   MPFR_ASSERTN(inexact == 0);
59 
60   /* check x = -0 */
61   mpfr_set_zero (x, -1);
62   inexact = mpfr_tanu (y, x, 1, MPFR_RNDN);
63   MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) != 0);
64   MPFR_ASSERTN(inexact == 0);
65 
66   mpfr_clear (x);
67   mpfr_clear (y);
68 }
69 
70 static void
test_exact(void)71 test_exact (void)
72 {
73   mpfr_t x, y;
74   int inexact, n;
75 
76   mpfr_init2 (x, 6);
77   mpfr_init2 (y, 6);
78 
79   /* check n + 0.5 for n integer */
80   for (n = 0; n < 10; n++)
81     {
82       /* check 2n+0.5 for n>=0: +Inf and divide by 0 exception */
83       mpfr_set_ui (x, 4 * n + 1, MPFR_RNDN);
84       mpfr_clear_divby0 ();
85       inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
86       MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
87       MPFR_ASSERTN(inexact == 0);
88       MPFR_ASSERTN(mpfr_divby0_p ());
89 
90       /* check 2n+1 for n>=0: -0 */
91       mpfr_set_ui (x, 4 * n + 2, MPFR_RNDN);
92       mpfr_clear_divby0 ();
93       inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
94       MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) != 0);
95       MPFR_ASSERTN(inexact == 0);
96       MPFR_ASSERTN(!mpfr_divby0_p ());
97 
98       /* check 2n+1.5 for n>=0: -Inf and divide by 0 exception */
99       mpfr_set_ui (x, 4 * n + 3, MPFR_RNDN);
100       mpfr_clear_divby0 ();
101       inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
102       MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) < 0);
103       MPFR_ASSERTN(inexact == 0);
104       MPFR_ASSERTN(mpfr_divby0_p ());
105 
106       /* check 2n+2 for n>=0: +0 */
107       mpfr_set_ui (x, 4 * n + 4, MPFR_RNDN);
108       mpfr_clear_divby0 ();
109       inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
110       MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
111       MPFR_ASSERTN(inexact == 0);
112       MPFR_ASSERTN(!mpfr_divby0_p ());
113 
114       /* check -2n-0.5 for n>=0: -Inf and divide by 0 exception */
115       mpfr_set_si (x, -4 * n - 1, MPFR_RNDN);
116       mpfr_clear_divby0 ();
117       inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
118       MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) < 0);
119       MPFR_ASSERTN(inexact == 0);
120       MPFR_ASSERTN(mpfr_divby0_p ());
121 
122       /* check -2n-1 for n>=0: +0 */
123       mpfr_set_si (x, -4 * n - 2, MPFR_RNDN);
124       mpfr_clear_divby0 ();
125       inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
126       MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
127       MPFR_ASSERTN(inexact == 0);
128       MPFR_ASSERTN(!mpfr_divby0_p ());
129 
130       /* check -2n-1.5 for n>=0: +Inf and divide by 0 exception */
131       mpfr_set_si (x, -4 * n - 3, MPFR_RNDN);
132       mpfr_clear_divby0 ();
133       inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
134       MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
135       MPFR_ASSERTN(inexact == 0);
136       MPFR_ASSERTN(mpfr_divby0_p ());
137 
138       /* check -2n-2 for n>=0: -0 */
139       mpfr_set_si (x, -4 * n - 4, MPFR_RNDN);
140       mpfr_clear_divby0 ();
141       inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
142       MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) != 0);
143       MPFR_ASSERTN(inexact == 0);
144       MPFR_ASSERTN(!mpfr_divby0_p ());
145     }
146 
147   /* check 2*pi*x/u = pi/4 thus x/u = 1/8, for example x=1 and u=8 */
148   mpfr_set_ui (x, 1, MPFR_RNDN);
149   inexact = mpfr_tanu (y, x, 8, MPFR_RNDN);
150   MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0 && inexact == 0);
151 
152   /* check 2*pi*x/u = 3*pi/4 thus x/u = 3/8, for example x=3 and u=8 */
153   mpfr_set_ui (x, 3, MPFR_RNDN);
154   inexact = mpfr_tanu (y, x, 8, MPFR_RNDN);
155   MPFR_ASSERTN(mpfr_cmp_si (y, -1) == 0 && inexact == 0);
156 
157   /* check 2*pi*x/u = 5*pi/4 thus x/u = 5/8, for example x=5 and u=8 */
158   mpfr_set_ui (x, 5, MPFR_RNDN);
159   inexact = mpfr_tanu (y, x, 8, MPFR_RNDN);
160   MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0 && inexact == 0);
161 
162   /* check 2*pi*x/u = 7*pi/4 thus x/u = 7/8, for example x=7 and u=8 */
163   mpfr_set_ui (x, 7, MPFR_RNDN);
164   inexact = mpfr_tanu (y, x, 8, MPFR_RNDN);
165   MPFR_ASSERTN(mpfr_cmp_si (y, -1) == 0 && inexact == 0);
166 
167   mpfr_clear (x);
168   mpfr_clear (y);
169 }
170 
171 static void
test_regular(void)172 test_regular (void)
173 {
174   mpfr_t x, y, z;
175   int inexact;
176 
177   mpfr_init2 (x, 53);
178   mpfr_init2 (y, 53);
179   mpfr_init2 (z, 53);
180 
181   mpfr_set_ui (x, 17, MPFR_RNDN);
182   inexact = mpfr_tanu (y, x, 42, MPFR_RNDN);
183   /* y should be tan(2*17*pi/42) rounded to nearest */
184   mpfr_set_str (z, "-0xa.e89b03074638p-4", 16, MPFR_RNDN);
185   MPFR_ASSERTN(mpfr_equal_p (y, z));
186   MPFR_ASSERTN(inexact > 0);
187 
188   mpfr_clear (x);
189   mpfr_clear (y);
190   mpfr_clear (z);
191 }
192 
193 /* Check argument reduction with large hard-coded inputs. The following
194    values were generated with gen_random(tan,10,53,100,20), where the
195    Sage code for gen_random is given in the tcosu.c file. */
196 static void
test_large(void)197 test_large (void)
198 {
199   static struct {
200     const char *x;
201     unsigned long u;
202     const char *y;
203   } t[] = {
204     { "-0x1.8f7cb49edc03p+16", 28, "0x4.c869fd8050554p-4" },
205     { "-0xe.8ede30716292p+16", 17, "-0x2.c83df69d8fdecp+4" },
206     { "-0x8.f14a73a7b4a3p+16", 4, "-0xd.be24a6d0fde98p-4" },
207     { "0xe.f82c4537b473p+16", 93, "-0x5.d0d95fdc8ffbcp+0" },
208     { "0x8.4148f00c8418p+16", 50, "0x1.e4e4aa652b2a4p-4" },
209     { "-0x6.e8b69db10e63p+16", 27, "-0x2.4f32f1977b7b2p-4" },
210     { "-0xe.a3ebf225ea2fp+16", 18, "0x6.5f7637f74517p+0" },
211     { "-0x5.580eb29168d8p+16", 92, "0x8.96418eed84e8p+0" },
212     { "0x8.13c5a1b43231p+16", 19, "0xb.2718b861b29fp-8" },
213     { "0x4.eb4e546e042dp+16", 64, "0x6.0b3ba821e4ep+0" }
214   };
215   int i;
216   mpfr_t x, y, z;
217 
218   mpfr_inits2 (53, x, y, z, (mpfr_ptr) 0);
219   for (i = 0; i < numberof (t); i++)
220     {
221       mpfr_set_str (x, t[i].x, 0, MPFR_RNDN);
222       mpfr_set_str (y, t[i].y, 0, MPFR_RNDN);
223       mpfr_tanu (z, x, t[i].u, MPFR_RNDN);
224       MPFR_ASSERTN (mpfr_equal_p (y, z));
225     }
226   mpfr_clears (x, y, z, (mpfr_ptr) 0);
227 }
228 
229 #define TEST_FUNCTION mpfr_tanu
230 #define ULONG_ARG2
231 #include "tgeneric.c"
232 
233 static int
mpfr_tan2pi(mpfr_ptr y,mpfr_srcptr x,mpfr_rnd_t r)234 mpfr_tan2pi (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r)
235 {
236   return mpfr_tanu (y, x, 1, r);
237 }
238 
239 int
main(void)240 main (void)
241 {
242   tests_start_mpfr ();
243 
244   test_singular ();
245   test_exact ();
246   test_regular ();
247   test_large ();
248 
249   test_generic (MPFR_PREC_MIN, 100, 1000);
250 
251   data_check ("data/tan2pi", mpfr_tan2pi, "mpfr_tan2pi");
252 
253   tests_end_mpfr ();
254   return 0;
255 }
256