1 | /* |
2 | * IBM Accurate Mathematical Library |
3 | * written by International Business Machines Corp. |
4 | * Copyright (C) 2001-2020 Free Software Foundation, Inc. |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU Lesser General Public License as published by |
8 | * the Free Software Foundation; either version 2.1 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU Lesser General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU Lesser General Public License |
17 | * along with this program; if not, see <https://www.gnu.org/licenses/>. |
18 | */ |
19 | /********************************************************************/ |
20 | /* */ |
21 | /* MODULE_NAME: dosincos.c */ |
22 | /* */ |
23 | /* */ |
24 | /* FUNCTIONS: dubsin */ |
25 | /* dubcos */ |
26 | /* docos */ |
27 | /* FILES NEEDED: endian.h mydefs.h dla.h dosincos.h */ |
28 | /* sincos.tbl */ |
29 | /* */ |
30 | /* Routines compute sin() and cos() as Double-Length numbers */ |
31 | /********************************************************************/ |
32 | |
33 | |
34 | |
35 | #include "endian.h" |
36 | #include "mydefs.h" |
37 | #include <dla.h> |
38 | #include "dosincos.h" |
39 | #include <math_private.h> |
40 | |
41 | #ifndef SECTION |
42 | # define SECTION |
43 | #endif |
44 | |
45 | extern const union |
46 | { |
47 | int4 i[880]; |
48 | double x[440]; |
49 | } __sincostab attribute_hidden; |
50 | |
51 | /***********************************************************************/ |
52 | /* Routine receive Double-Length number (x+dx) and computing sin(x+dx) */ |
53 | /* as Double-Length number and store it at array v .It computes it by */ |
54 | /* arithmetic action on Double-Length numbers */ |
55 | /*(x+dx) between 0 and PI/4 */ |
56 | /***********************************************************************/ |
57 | |
58 | void |
59 | SECTION |
60 | __dubsin (double x, double dx, double v[]) |
61 | { |
62 | double r, s, c, cc, d, dd, d2, dd2, e, ee, |
63 | sn, ssn, cs, ccs, ds, dss, dc, dcc; |
64 | mynumber u; |
65 | int4 k; |
66 | |
67 | u.x = x + big.x; |
68 | k = u.i[LOW_HALF] << 2; |
69 | x = x - (u.x - big.x); |
70 | d = x + dx; |
71 | dd = (x - d) + dx; |
72 | /* sin(x+dx)=sin(Xi+t)=sin(Xi)*cos(t) + cos(Xi)sin(t) where t ->0 */ |
73 | MUL2 (d, dd, d, dd, d2, dd2, c, cc); |
74 | sn = __sincostab.x[k]; /* */ |
75 | ssn = __sincostab.x[k + 1]; /* sin(Xi) and cos(Xi) */ |
76 | cs = __sincostab.x[k + 2]; /* */ |
77 | ccs = __sincostab.x[k + 3]; /* */ |
78 | /* Taylor series for sin ds=sin(t) */ |
79 | MUL2 (d2, dd2, s7.x, ss7.x, ds, dss, c, cc); |
80 | ADD2 (ds, dss, s5.x, ss5.x, ds, dss, r, s); |
81 | MUL2 (d2, dd2, ds, dss, ds, dss, c, cc); |
82 | ADD2 (ds, dss, s3.x, ss3.x, ds, dss, r, s); |
83 | MUL2 (d2, dd2, ds, dss, ds, dss, c, cc); |
84 | MUL2 (d, dd, ds, dss, ds, dss, c, cc); |
85 | ADD2 (ds, dss, d, dd, ds, dss, r, s); |
86 | |
87 | /* Taylor series for cos dc=cos(t) */ |
88 | MUL2 (d2, dd2, c8.x, cc8.x, dc, dcc, c, cc); |
89 | ADD2 (dc, dcc, c6.x, cc6.x, dc, dcc, r, s); |
90 | MUL2 (d2, dd2, dc, dcc, dc, dcc, c, cc); |
91 | ADD2 (dc, dcc, c4.x, cc4.x, dc, dcc, r, s); |
92 | MUL2 (d2, dd2, dc, dcc, dc, dcc, c, cc); |
93 | ADD2 (dc, dcc, c2.x, cc2.x, dc, dcc, r, s); |
94 | MUL2 (d2, dd2, dc, dcc, dc, dcc, c, cc); |
95 | |
96 | MUL2 (cs, ccs, ds, dss, e, ee, c, cc); |
97 | MUL2 (dc, dcc, sn, ssn, dc, dcc, c, cc); |
98 | SUB2 (e, ee, dc, dcc, e, ee, r, s); |
99 | ADD2 (e, ee, sn, ssn, e, ee, r, s); /* e+ee=sin(x+dx) */ |
100 | |
101 | v[0] = e; |
102 | v[1] = ee; |
103 | } |
104 | /**********************************************************************/ |
105 | /* Routine receive Double-Length number (x+dx) and computes cos(x+dx) */ |
106 | /* as Double-Length number and store it in array v .It computes it by */ |
107 | /* arithmetic action on Double-Length numbers */ |
108 | /*(x+dx) between 0 and PI/4 */ |
109 | /**********************************************************************/ |
110 | |
111 | void |
112 | SECTION |
113 | __dubcos (double x, double dx, double v[]) |
114 | { |
115 | double r, s, c, cc, d, dd, d2, dd2, e, ee, |
116 | sn, ssn, cs, ccs, ds, dss, dc, dcc; |
117 | mynumber u; |
118 | int4 k; |
119 | u.x = x + big.x; |
120 | k = u.i[LOW_HALF] << 2; |
121 | x = x - (u.x - big.x); |
122 | d = x + dx; |
123 | dd = (x - d) + dx; /* cos(x+dx)=cos(Xi+t)=cos(Xi)cos(t) - sin(Xi)sin(t) */ |
124 | MUL2 (d, dd, d, dd, d2, dd2, c, cc); |
125 | sn = __sincostab.x[k]; /* */ |
126 | ssn = __sincostab.x[k + 1]; /* sin(Xi) and cos(Xi) */ |
127 | cs = __sincostab.x[k + 2]; /* */ |
128 | ccs = __sincostab.x[k + 3]; /* */ |
129 | MUL2 (d2, dd2, s7.x, ss7.x, ds, dss, c, cc); |
130 | ADD2 (ds, dss, s5.x, ss5.x, ds, dss, r, s); |
131 | MUL2 (d2, dd2, ds, dss, ds, dss, c, cc); |
132 | ADD2 (ds, dss, s3.x, ss3.x, ds, dss, r, s); |
133 | MUL2 (d2, dd2, ds, dss, ds, dss, c, cc); |
134 | MUL2 (d, dd, ds, dss, ds, dss, c, cc); |
135 | ADD2 (ds, dss, d, dd, ds, dss, r, s); |
136 | |
137 | MUL2 (d2, dd2, c8.x, cc8.x, dc, dcc, c, cc); |
138 | ADD2 (dc, dcc, c6.x, cc6.x, dc, dcc, r, s); |
139 | MUL2 (d2, dd2, dc, dcc, dc, dcc, c, cc); |
140 | ADD2 (dc, dcc, c4.x, cc4.x, dc, dcc, r, s); |
141 | MUL2 (d2, dd2, dc, dcc, dc, dcc, c, cc); |
142 | ADD2 (dc, dcc, c2.x, cc2.x, dc, dcc, r, s); |
143 | MUL2 (d2, dd2, dc, dcc, dc, dcc, c, cc); |
144 | |
145 | MUL2 (cs, ccs, ds, dss, e, ee, c, cc); |
146 | MUL2 (dc, dcc, sn, ssn, dc, dcc, c, cc); |
147 | |
148 | MUL2 (d2, dd2, s7.x, ss7.x, ds, dss, c, cc); |
149 | ADD2 (ds, dss, s5.x, ss5.x, ds, dss, r, s); |
150 | MUL2 (d2, dd2, ds, dss, ds, dss, c, cc); |
151 | ADD2 (ds, dss, s3.x, ss3.x, ds, dss, r, s); |
152 | MUL2 (d2, dd2, ds, dss, ds, dss, c, cc); |
153 | MUL2 (d, dd, ds, dss, ds, dss, c, cc); |
154 | ADD2 (ds, dss, d, dd, ds, dss, r, s); |
155 | MUL2 (d2, dd2, c8.x, cc8.x, dc, dcc, c, cc); |
156 | ADD2 (dc, dcc, c6.x, cc6.x, dc, dcc, r, s); |
157 | MUL2 (d2, dd2, dc, dcc, dc, dcc, c, cc); |
158 | ADD2 (dc, dcc, c4.x, cc4.x, dc, dcc, r, s); |
159 | MUL2 (d2, dd2, dc, dcc, dc, dcc, c, cc); |
160 | ADD2 (dc, dcc, c2.x, cc2.x, dc, dcc, r, s); |
161 | MUL2 (d2, dd2, dc, dcc, dc, dcc, c, cc); |
162 | MUL2 (sn, ssn, ds, dss, e, ee, c, cc); |
163 | MUL2 (dc, dcc, cs, ccs, dc, dcc, c, cc); |
164 | ADD2 (e, ee, dc, dcc, e, ee, r, s); |
165 | SUB2 (cs, ccs, e, ee, e, ee, r, s); |
166 | |
167 | v[0] = e; |
168 | v[1] = ee; |
169 | } |
170 | /**********************************************************************/ |
171 | /* Routine receive Double-Length number (x+dx) and computes cos(x+dx) */ |
172 | /* as Double-Length number and store it in array v */ |
173 | /**********************************************************************/ |
174 | void |
175 | SECTION |
176 | __docos (double x, double dx, double v[]) |
177 | { |
178 | double y, yy, p, w[2]; |
179 | if (x > 0) |
180 | { |
181 | y = x; yy = dx; |
182 | } |
183 | else |
184 | { |
185 | y = -x; yy = -dx; |
186 | } |
187 | if (y < 0.5 * hp0.x) /* y< PI/4 */ |
188 | { |
189 | __dubcos (y, yy, w); v[0] = w[0]; v[1] = w[1]; |
190 | } |
191 | else if (y < 1.5 * hp0.x) /* y< 3/4 * PI */ |
192 | { |
193 | p = hp0.x - y; /* p = PI/2 - y */ |
194 | yy = hp1.x - yy; |
195 | y = p + yy; |
196 | yy = (p - y) + yy; |
197 | if (y > 0) |
198 | { |
199 | __dubsin (y, yy, w); v[0] = w[0]; v[1] = w[1]; |
200 | } |
201 | /* cos(x) = sin ( 90 - x ) */ |
202 | else |
203 | { |
204 | __dubsin (-y, -yy, w); v[0] = -w[0]; v[1] = -w[1]; |
205 | } |
206 | } |
207 | else /* y>= 3/4 * PI */ |
208 | { |
209 | p = 2.0 * hp0.x - y; /* p = PI- y */ |
210 | yy = 2.0 * hp1.x - yy; |
211 | y = p + yy; |
212 | yy = (p - y) + yy; |
213 | __dubcos (y, yy, w); |
214 | v[0] = -w[0]; |
215 | v[1] = -w[1]; |
216 | } |
217 | } |
218 | |