annotate libgfortran/intrinsics/trigd.inc @ 152:2b5abeee2509

update gcc11
author anatofuz
date Mon, 25 May 2020 07:50:57 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
152
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
1 /* Implementation of the degree trignometric functions COSD, SIND, TAND.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
2 Copyright (C) 2020 Free Software Foundation, Inc.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
3 Contributed by Steven G. Kargl <kargl@gcc.gnu.org>
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
4 and Fritz Reese <foreese@gcc.gnu.org>
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
5
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
6 This file is part of the GNU Fortran runtime library (libgfortran).
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
7
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
8 Libgfortran is free software; you can redistribute it and/or
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
9 modify it under the terms of the GNU General Public
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
10 License as published by the Free Software Foundation; either
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
11 version 3 of the License, or (at your option) any later version.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
12
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
13 Libgfortran is distributed in the hope that it will be useful,
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
16 GNU General Public License for more details.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
17
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
18 Under Section 7 of GPL version 3, you are granted additional
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
19 permissions described in the GCC Runtime Library Exception, version
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
20 3.1, as published by the Free Software Foundation.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
21
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
22 You should have received a copy of the GNU General Public License and
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
23 a copy of the GCC Runtime Library Exception along with this program;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
25 <http://www.gnu.org/licenses/>. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
26
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
27
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
28 /*
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
29
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
30 This file is included from both the FE and the runtime library code.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
31 Operations are generalized using GMP/MPFR functions. When included from
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
32 libgfortran, these should be overridden using macros which will use native
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
33 operations conforming to the same API. From the FE, the GMP/MPFR functions can
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
34 be used as-is.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
35
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
36 The following macros are used and must be defined, unless listed as [optional]:
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
37
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
38 FTYPE
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
39 Type name for the real-valued parameter.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
40 Variables of this type are constructed/destroyed using mpfr_init()
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
41 and mpfr_clear.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
42
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
43 RETTYPE
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
44 Return type of the functions.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
45
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
46 RETURN(x)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
47 Insert code to return a value.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
48 The parameter x is the result variable, which was also the input parameter.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
49
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
50 ITYPE
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
51 Type name for integer types.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
52
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
53 SIND, COSD, TRIGD
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
54 Names for the degree-valued trig functions defined by this module.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
55
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
56 ENABLE_SIND, ENABLE_COSD, ENABLE_TAND
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
57 Whether the degree-valued trig functions can be enabled.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
58
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
59 ERROR_RETURN(f, k, x)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
60 If ENABLE_<xxx>D is not defined, this is substituted to assert an
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
61 error condition for function f, kind k, and parameter x.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
62 The function argument is one of {sind, cosd, tand}.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
63
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
64 ISFINITE(x)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
65 Whether x is a regular number or zero (not inf or NaN).
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
66
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
67 D2R(x)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
68 Convert x from radians to degrees.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
69
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
70 SET_COSD30(x)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
71 Set x to COSD(30), or equivalently, SIND(60).
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
72
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
73 TINY_LITERAL [optional]
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
74 Value subtracted from 1 to cause raise INEXACT for COSD(x) for x << 1.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
75 If not set, COSD(x) for x <= COSD_SMALL_LITERAL simply returns 1.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
76
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
77 COSD_SMALL_LITERAL [optional]
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
78 Value such that x <= COSD_SMALL_LITERAL implies COSD(x) = 1 to within the
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
79 precision of FTYPE. If not set, this condition is not checked.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
80
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
81 SIND_SMALL_LITERAL [optional]
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
82 Value such that x <= SIND_SMALL_LITERAL implies SIND(x) = D2R(x) to within
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
83 the precision of FTYPE. If not set, this condition is not checked.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
84
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
85 */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
86
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
87
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
88 #ifdef SIND
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
89 /* Compute sind(x) = sin(x * pi / 180). */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
90
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
91 RETTYPE
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
92 SIND (FTYPE x)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
93 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
94 #ifdef ENABLE_SIND
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
95 if (ISFINITE (x))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
96 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
97 FTYPE s, one;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
98
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
99 /* sin(-x) = - sin(x). */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
100 mpfr_init (s);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
101 mpfr_init_set_ui (one, 1, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
102 mpfr_copysign (s, one, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
103 mpfr_clear (one);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
104
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
105 #ifdef SIND_SMALL_LITERAL
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
106 /* sin(x) = x as x -> 0; but only for some precisions. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
107 FTYPE ax;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
108 mpfr_init (ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
109 mpfr_abs (ax, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
110 if (mpfr_cmp_ld (ax, SIND_SMALL_LITERAL) < 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
111 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
112 D2R (x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
113 mpfr_clear (ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
114 return x;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
115 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
116
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
117 mpfr_swap (x, ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
118 mpfr_clear (ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
119
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
120 #else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
121 mpfr_abs (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
122 #endif /* SIND_SMALL_LITERAL */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
123
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
124 /* Reduce angle to x in [0,360]. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
125 FTYPE period;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
126 mpfr_init_set_ui (period, 360, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
127 mpfr_fmod (x, x, period, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
128 mpfr_clear (period);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
129
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
130 /* Special cases with exact results. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
131 ITYPE n;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
132 mpz_init (n);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
133 if (mpfr_get_z (n, x, GFC_RND_MODE) == 0 && mpz_divisible_ui_p (n, 30))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
134 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
135 /* Flip sign for odd n*pi (x is % 360 so this is only for 180).
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
136 This respects sgn(sin(x)) = sgn(d/dx sin(x)) = sgn(cos(x)). */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
137 if (mpz_divisible_ui_p (n, 180))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
138 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
139 mpfr_set_ui (x, 0, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
140 if (mpz_cmp_ui (n, 180) == 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
141 mpfr_neg (s, s, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
142 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
143 else if (mpz_divisible_ui_p (n, 90))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
144 mpfr_set_si (x, (mpz_cmp_ui (n, 90) == 0 ? 1 : -1), GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
145 else if (mpz_divisible_ui_p (n, 60))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
146 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
147 SET_COSD30 (x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
148 if (mpz_cmp_ui (n, 180) >= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
149 mpfr_neg (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
150 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
151 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
152 mpfr_set_ld (x, (mpz_cmp_ui (n, 180) < 0 ? 0.5L : -0.5L),
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
153 GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
154 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
155
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
156 /* Fold [0,360] into the range [0,45], and compute either SIN() or
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
157 COS() depending on symmetry of shifting into the [0,45] range. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
158 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
159 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
160 bool fold_cos = false;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
161 if (mpfr_cmp_ui (x, 180) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
162 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
163 if (mpfr_cmp_ui (x, 90) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
164 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
165 if (mpfr_cmp_ui (x, 45) > 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
166 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
167 /* x = COS(D2R(90 - x)) */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
168 mpfr_ui_sub (x, 90, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
169 fold_cos = true;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
170 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
171 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
172 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
173 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
174 if (mpfr_cmp_ui (x, 135) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
175 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
176 mpfr_sub_ui (x, x, 90, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
177 fold_cos = true;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
178 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
179 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
180 mpfr_ui_sub (x, 180, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
181 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
182 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
183
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
184 else if (mpfr_cmp_ui (x, 270) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
185 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
186 if (mpfr_cmp_ui (x, 225) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
187 mpfr_sub_ui (x, x, 180, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
188 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
189 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
190 mpfr_ui_sub (x, 270, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
191 fold_cos = true;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
192 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
193 mpfr_neg (s, s, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
194 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
195
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
196 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
197 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
198 if (mpfr_cmp_ui (x, 315) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
199 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
200 mpfr_sub_ui (x, x, 270, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
201 fold_cos = true;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
202 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
203 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
204 mpfr_ui_sub (x, 360, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
205 mpfr_neg (s, s, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
206 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
207
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
208 D2R (x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
209
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
210 if (fold_cos)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
211 mpfr_cos (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
212 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
213 mpfr_sin (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
214 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
215
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
216 mpfr_mul (x, x, s, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
217 mpz_clear (n);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
218 mpfr_clear (s);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
219 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
220
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
221 /* Return NaN for +-Inf and NaN and raise exception. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
222 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
223 mpfr_sub (x, x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
224
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
225 RETURN (x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
226
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
227 #else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
228 ERROR_RETURN(sind, KIND, x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
229 #endif // ENABLE_SIND
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
230 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
231 #endif // SIND
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
232
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
233
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
234 #ifdef COSD
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
235 /* Compute cosd(x) = cos(x * pi / 180). */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
236
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
237 RETTYPE
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
238 COSD (FTYPE x)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
239 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
240 #ifdef ENABLE_COSD
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
241 #if defined(TINY_LITERAL) && defined(COSD_SMALL_LITERAL)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
242 static const volatile FTYPE tiny = TINY_LITERAL;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
243 #endif
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
244
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
245 if (ISFINITE (x))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
246 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
247 #ifdef COSD_SMALL_LITERAL
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
248 FTYPE ax;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
249 mpfr_init (ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
250
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
251 mpfr_abs (ax, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
252 /* No spurious underflows!. In radians, cos(x) = 1-x*x/2 as x -> 0. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
253 if (mpfr_cmp_ld (ax, COSD_SMALL_LITERAL) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
254 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
255 mpfr_set_ui (x, 1, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
256 #ifdef TINY_LITERAL
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
257 /* Cause INEXACT. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
258 if (!mpfr_zero_p (ax))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
259 mpfr_sub_d (x, x, tiny, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
260 #endif
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
261
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
262 mpfr_clear (ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
263 return x;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
264 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
265
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
266 mpfr_swap (x, ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
267 mpfr_clear (ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
268 #else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
269 mpfr_abs (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
270 #endif /* COSD_SMALL_LITERAL */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
271
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
272 /* Reduce angle to ax in [0,360]. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
273 FTYPE period;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
274 mpfr_init_set_ui (period, 360, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
275 mpfr_fmod (x, x, period, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
276 mpfr_clear (period);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
277
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
278 /* Special cases with exact results.
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
279 Return negative zero for cosd(270) for consistency with libm cos(). */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
280 ITYPE n;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
281 mpz_init (n);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
282 if (mpfr_get_z (n, x, GFC_RND_MODE) == 0 && mpz_divisible_ui_p (n, 30))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
283 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
284 if (mpz_divisible_ui_p (n, 180))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
285 mpfr_set_si (x, (mpz_cmp_ui (n, 180) == 0 ? -1 : 1),
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
286 GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
287 else if (mpz_divisible_ui_p (n, 90))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
288 mpfr_set_zero (x, 0);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
289 else if (mpz_divisible_ui_p (n, 60))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
290 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
291 mpfr_set_ld (x, 0.5, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
292 if (mpz_cmp_ui (n, 60) != 0 && mpz_cmp_ui (n, 300) != 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
293 mpfr_neg (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
294 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
295 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
296 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
297 SET_COSD30 (x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
298 if (mpz_cmp_ui (n, 30) != 0 && mpz_cmp_ui (n, 330) != 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
299 mpfr_neg (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
300 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
301 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
302
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
303 /* Fold [0,360] into the range [0,45], and compute either SIN() or
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
304 COS() depending on symmetry of shifting into the [0,45] range. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
305 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
306 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
307 bool neg = false;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
308 bool fold_sin = false;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
309 if (mpfr_cmp_ui (x, 180) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
310 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
311 if (mpfr_cmp_ui (x, 90) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
312 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
313 if (mpfr_cmp_ui (x, 45) > 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
314 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
315 mpfr_ui_sub (x, 90, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
316 fold_sin = true;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
317 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
318 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
319 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
320 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
321 if (mpfr_cmp_ui (x, 135) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
322 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
323 mpfr_sub_ui (x, x, 90, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
324 fold_sin = true;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
325 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
326 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
327 mpfr_ui_sub (x, 180, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
328 neg = true;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
329 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
330 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
331
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
332 else if (mpfr_cmp_ui (x, 270) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
333 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
334 if (mpfr_cmp_ui (x, 225) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
335 mpfr_sub_ui (x, x, 180, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
336 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
337 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
338 mpfr_ui_sub (x, 270, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
339 fold_sin = true;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
340 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
341 neg = true;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
342 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
343
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
344 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
345 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
346 if (mpfr_cmp_ui (x, 315) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
347 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
348 mpfr_sub_ui (x, x, 270, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
349 fold_sin = true;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
350 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
351 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
352 mpfr_ui_sub (x, 360, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
353 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
354
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
355 D2R (x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
356
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
357 if (fold_sin)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
358 mpfr_sin (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
359 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
360 mpfr_cos (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
361
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
362 if (neg)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
363 mpfr_neg (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
364 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
365
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
366 mpz_clear (n);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
367 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
368
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
369 /* Return NaN for +-Inf and NaN and raise exception. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
370 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
371 mpfr_sub (x, x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
372
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
373 RETURN (x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
374
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
375 #else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
376 ERROR_RETURN(cosd, KIND, x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
377 #endif // ENABLE_COSD
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
378 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
379 #endif // COSD
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
380
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
381
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
382 #ifdef TAND
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
383 /* Compute tand(x) = tan(x * pi / 180). */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
384
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
385 RETTYPE
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
386 TAND (FTYPE x)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
387 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
388 #ifdef ENABLE_TAND
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
389 if (ISFINITE (x))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
390 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
391 FTYPE s, one;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
392
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
393 /* tan(-x) = - tan(x). */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
394 mpfr_init (s);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
395 mpfr_init_set_ui (one, 1, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
396 mpfr_copysign (s, one, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
397 mpfr_clear (one);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
398
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
399 #ifdef SIND_SMALL_LITERAL
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
400 /* tan(x) = x as x -> 0; but only for some precisions. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
401 FTYPE ax;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
402 mpfr_init (ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
403 mpfr_abs (ax, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
404 if (mpfr_cmp_ld (ax, SIND_SMALL_LITERAL) < 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
405 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
406 D2R (x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
407 mpfr_clear (ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
408 return x;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
409 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
410
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
411 mpfr_swap (x, ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
412 mpfr_clear (ax);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
413
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
414 #else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
415 mpfr_abs (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
416 #endif /* SIND_SMALL_LITERAL */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
417
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
418 /* Reduce angle to x in [0,360]. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
419 FTYPE period;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
420 mpfr_init_set_ui (period, 360, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
421 mpfr_fmod (x, x, period, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
422 mpfr_clear (period);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
423
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
424 /* Special cases with exact results. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
425 ITYPE n;
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
426 mpz_init (n);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
427 if (mpfr_get_z (n, x, GFC_RND_MODE) == 0 && mpz_divisible_ui_p (n, 45))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
428 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
429 if (mpz_divisible_ui_p (n, 180))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
430 mpfr_set_zero (x, 0);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
431
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
432 /* Though mathematically NaN is more appropriate for tan(n*90),
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
433 returning +/-Inf offers the advantage that 1/tan(n*90) returns 0,
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
434 which is mathematically sound. In fact we rely on this behavior
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
435 to implement COTAND(x) = 1 / TAND(x).
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
436 */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
437 else if (mpz_divisible_ui_p (n, 90))
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
438 mpfr_set_inf (x, mpz_cmp_ui (n, 90) == 0 ? 0 : 1);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
439
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
440 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
441 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
442 mpfr_set_ui (x, 1, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
443 if (mpz_cmp_ui (n, 45) != 0 && mpz_cmp_ui (n, 225) != 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
444 mpfr_neg (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
445 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
446 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
447
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
448 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
449 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
450 /* Fold [0,360] into the range [0,90], and compute TAN(). */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
451 if (mpfr_cmp_ui (x, 180) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
452 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
453 if (mpfr_cmp_ui (x, 90) > 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
454 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
455 mpfr_ui_sub (x, 180, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
456 mpfr_neg (s, s, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
457 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
458 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
459 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
460 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
461 if (mpfr_cmp_ui (x, 270) <= 0)
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
462 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
463 mpfr_sub_ui (x, x, 180, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
464 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
465 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
466 {
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
467 mpfr_ui_sub (x, 360, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
468 mpfr_neg (s, s, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
469 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
470 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
471
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
472 D2R (x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
473 mpfr_tan (x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
474 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
475
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
476 mpfr_mul (x, x, s, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
477 mpz_clear (n);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
478 mpfr_clear (s);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
479 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
480
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
481 /* Return NaN for +-Inf and NaN and raise exception. */
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
482 else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
483 mpfr_sub (x, x, x, GFC_RND_MODE);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
484
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
485 RETURN (x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
486
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
487 #else
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
488 ERROR_RETURN(tand, KIND, x);
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
489 #endif // ENABLE_TAND
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
490 }
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
491 #endif // TAND
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
492
2b5abeee2509 update gcc11
anatofuz
parents:
diff changeset
493 /* vim: set ft=c: */