xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/ttan.c (revision ba125506a622fe649968631a56eba5d42ff57863)
1 /* Test file for mpfr_tan.
2 
3 Copyright 2001-2004, 2006-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_tan
26 #define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */
27 #include "tgeneric.c"
28 
29 static void
check_nans(void)30 check_nans (void)
31 {
32   mpfr_t  x, y;
33 
34   mpfr_init2 (x, 123L);
35   mpfr_init2 (y, 123L);
36 
37   mpfr_set_nan (x);
38   mpfr_tan (y, x, MPFR_RNDN);
39   if (! mpfr_nan_p (y))
40     {
41       printf ("Error: tan(NaN) != NaN\n");
42       exit (1);
43     }
44 
45   mpfr_set_inf (x, 1);
46   mpfr_tan (y, x, MPFR_RNDN);
47   if (! mpfr_nan_p (y))
48     {
49       printf ("Error: tan(Inf) != NaN\n");
50       exit (1);
51     }
52 
53   mpfr_set_inf (x, -1);
54   mpfr_tan (y, x, MPFR_RNDN);
55   if (! mpfr_nan_p (y))
56     {
57       printf ("Error: tan(-Inf) != NaN\n");
58       exit (1);
59     }
60 
61   /* exercise recomputation */
62   mpfr_set_prec (x, 14);
63   mpfr_set_str_binary (x, "0.10100000101010E0");
64   mpfr_set_prec (y, 24);
65   mpfr_tan (y, x, MPFR_RNDU);
66   mpfr_set_prec (x, 24);
67   mpfr_set_str_binary (x, "101110011011001100100001E-24");
68   MPFR_ASSERTN(mpfr_cmp (x, y) == 0);
69 
70   /* Compute ~Pi/2 to check overflow */
71   mpfr_set_prec (x, 20000);
72   mpfr_const_pi (x, MPFR_RNDD);
73   mpfr_div_2ui (x, x, 1, MPFR_RNDN);
74   mpfr_set_prec (y, 24);
75   mpfr_tan (y, x, MPFR_RNDN);
76   if (mpfr_cmp_str (y, "0.100011101101011000100011E20001", 2, MPFR_RNDN))
77     {
78       printf("Error computing tan(~Pi/2)\n");
79       mpfr_dump (y);
80       exit (1);
81     }
82 
83   /* bug found by Kaveh Ghazi on 13 Jul 2007 */
84   mpfr_set_prec (x, 53);
85   mpfr_set_prec (y, 53);
86   mpfr_set_str_binary (x, "0.10011100110111000001000010110100101000000000000000000E34");
87   mpfr_tan (y, x, MPFR_RNDN);
88   mpfr_set_str_binary (x, "0.1000010011001010001000010100000110100111000011010101E41");
89   MPFR_ASSERTN(mpfr_cmp (x, y) == 0);
90 
91   mpfr_clear (x);
92   mpfr_clear (y);
93 }
94 
95 /* This test was generated from bad_cases, with GMP_CHECK_RANDOMIZE=1514257254.
96    For the x value below, we have tan(x) = -1.875 + epsilon,
97    thus with RNDZ it should be rounded to -1.c. */
98 static void
bug20171218(void)99 bug20171218 (void)
100 {
101   mpfr_t x, y, z;
102   mpfr_init2 (x, 804);
103   mpfr_init2 (y, 4);
104   mpfr_init2 (z, 4);
105   mpfr_set_str (x, "-1.14b1dd5f90ce0eded2a8f59c05e72daf7cc4c78f5075d73246fa420e2c026291d9377e67e7f54e925c4aed39c7b2f917424033c8612f00a19821890558d6c2cef9c60f4ad2c3b061ed53a1709dc1ec8e139627c2119c36d7ebdff0d715e559b47f740c534", 16, MPFR_RNDN);
106   mpfr_tan (y, x, MPFR_RNDZ);
107   mpfr_set_str (z, "-1.c", 16, MPFR_RNDN);
108   MPFR_ASSERTN(mpfr_equal_p (y, z));
109   mpfr_clear (x);
110   mpfr_clear (y);
111   mpfr_clear (z);
112 }
113 
114 static void
coverage(void)115 coverage (void)
116 {
117   mpfr_t x, y;
118   int inex;
119   mpfr_exp_t emax;
120 
121   /* exercise mpfr_round_near_x when rounding gives an overflow */
122   emax = mpfr_get_emax ();
123   set_emax (-2);
124   mpfr_init2 (x, 2);
125   mpfr_init2 (y, 2);
126   mpfr_setmax (x, mpfr_get_emax ());
127   inex = mpfr_tan (y, x, MPFR_RNDA);
128   MPFR_ASSERTN(inex > 0);
129   MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_signbit (y) == 0);
130   mpfr_clear (x);
131   mpfr_clear (y);
132   set_emax (emax);
133 }
134 
135 int
main(int argc,char * argv[])136 main (int argc, char *argv[])
137 {
138   mpfr_t x;
139   unsigned int i;
140   unsigned int prec[10] = {14, 15, 19, 22, 23, 24, 25, 40, 41, 52};
141   unsigned int prec2[10] = {4, 5, 6, 19, 70, 95, 100, 106, 107, 108};
142 
143   tests_start_mpfr ();
144 
145   coverage ();
146   bug20171218 ();
147   check_nans ();
148 
149   mpfr_init (x);
150 
151   mpfr_set_prec (x, 2);
152   mpfr_set_str (x, "0.5", 10, MPFR_RNDN);
153   mpfr_tan (x, x, MPFR_RNDD);
154   if (mpfr_cmp_ui_2exp(x, 1, -1))
155     {
156       printf ("mpfr_tan(0.5, MPFR_RNDD) failed\n"
157               "expected 0.5, got ");
158       mpfr_dump (x);
159       exit (1);
160     }
161 
162   /* check that tan(3*Pi/4) ~ -1 */
163   for (i=0; i<10; i++)
164     {
165       mpfr_set_prec (x, prec[i]);
166       mpfr_const_pi (x, MPFR_RNDN);
167       mpfr_mul_ui (x, x, 3, MPFR_RNDN);
168       mpfr_div_ui (x, x, 4, MPFR_RNDN);
169       mpfr_tan (x, x, MPFR_RNDN);
170       if (mpfr_cmp_si (x, -1))
171         {
172           printf ("tan(3*Pi/4) fails for prec=%u\n", prec[i]);
173           exit (1);
174         }
175     }
176 
177   /* check that tan(7*Pi/4) ~ -1 */
178   for (i=0; i<10; i++)
179     {
180       mpfr_set_prec (x, prec2[i]);
181       mpfr_const_pi (x, MPFR_RNDN);
182       mpfr_mul_ui (x, x, 7, MPFR_RNDN);
183       mpfr_div_ui (x, x, 4, MPFR_RNDN);
184       mpfr_tan (x, x, MPFR_RNDN);
185       if (mpfr_cmp_si (x, -1))
186         {
187           printf ("tan(3*Pi/4) fails for prec=%u\n", prec2[i]);
188           exit (1);
189         }
190     }
191 
192   mpfr_clear (x);
193 
194   test_generic (MPFR_PREC_MIN, 100, 10);
195 
196   data_check ("data/tan", mpfr_tan, "mpfr_tan");
197   bad_cases (mpfr_tan, mpfr_atan, "mpfr_tan", 256, -256, 255, 4, 128, 800, 40);
198 
199   tests_end_mpfr ();
200   return 0;
201 }
202