1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 */
25 /*
26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
28 */
29
30 /*
31 * Given X, __vlibm_rem_pio2m finds Y and an integer n such that
32 * Y = X - n*pi/2 and |Y| < pi/2.
33 *
34 * On entry, X is represented by x, an array of nx 24-bit integers
35 * stored in double precision format, and e:
36 *
37 * X = sum (x[i] * 2^(e - 24*i))
38 *
39 * nx must be 1, 2, or 3, and e must be >= -24. For example, a
40 * suitable representation for the double precision number z can
41 * be computed as follows:
42 *
43 * e = ilogb(z)-23
44 * z = scalbn(z,-e)
45 * for i = 0,1,2
46 * x[i] = floor(z)
47 * z = (z-x[i])*2**24
48 *
49 * On exit, Y is approximated by y[0] if prec is 0 and by the un-
50 * evaluated sum y[0] + y[1] if prec != 0. The approximation is
51 * accurate to 53 bits in the former case and to at least 72 bits
52 * in the latter.
53 *
54 * __vlibm_rem_pio2m returns n mod 8.
55 *
56 * Notes:
57 *
58 * As n is the integer nearest X * 2/pi, we approximate the latter
59 * product to a precision that is determined dynamically so as to
60 * ensure that the final value Y is approximated accurately enough.
61 * We don't bother to compute terms in the product that are multiples
62 * of 8, so the cost of this multiplication is independent of the
63 * magnitude of X. The variable ip determines the offset into the
64 * array ipio2 of the first term we need to use. The variable eq0
65 * is the corresponding exponent of the first partial product.
66 *
67 * The partial products are scaled, summed, and split into an array
68 * of non-overlapping 24-bit terms (not necessarily having the same
69 * signs). Each partial product overlaps three elements of the
70 * resulting array:
71 *
72 * q[i] xxxxxxxxxxxxxx
73 * q[i+1] xxxxxxxxxxxxxx
74 * q[i+2] xxxxxxxxxxxxxx
75 * ... ...
76 *
77 *
78 * r[i] xxxxxx
79 * r[i+1] xxxxxx
80 * r[i+2] xxxxxx
81 * ... ...
82 *
83 * In order that the last element of the r array have some correct
84 * bits, we compute an extra term in the q array, but we don't bother
85 * to split this last term into 24-bit chunks; thus, the final term
86 * of the r array could have more than 24 bits, but this doesn't
87 * matter.
88 *
89 * After we subtract the nearest integer to the product, we multiply
90 * the remaining part of r by pi/2 to obtain Y. Before we compute
91 * this last product, however, we make sure that the remaining part
92 * of r has at least five nonzero terms, computing more if need be.
93 * This ensures that even if the first nonzero term is only a single
94 * bit and the last term is wrong in several trailing bits, we still
95 * have enough accuracy to obtain 72 bits of Y.
96 *
97 * IMPORTANT: This code assumes that the rounding mode is round-to-
98 * nearest in several key places. First, after we compute X * 2/pi,
99 * we round to the nearest integer by adding and subtracting a power
100 * of two. This step must be done in round-to-nearest mode to ensure
101 * that the remainder is less than 1/2 in absolute value. (Because
102 * we only take two adjacent terms of r into account when we perform
103 * this rounding, in very rare cases the remainder could be just
104 * barely greater than 1/2, but this shouldn't matter in practice.)
105 *
106 * Second, we also split the partial products of X * 2/pi into 24-bit
107 * pieces by adding and subtracting a power of two. In this step,
108 * round-to-nearest mode is important in order to guarantee that
109 * the index of the first nonzero term in the remainder gives an
110 * accurate indication of the number of significant terms. For
111 * example, suppose eq0 = -1, so that r[1] is a multiple of 1/2 and
112 * |r[2]| < 1/2. After we subtract the nearest integer, r[1] could
113 * be -1/2, and r[2] could be very nearly 1/2, so that r[1] != 0,
114 * yet the remainder is much smaller than the least significant bit
115 * corresponding to r[1]. As long as we use round-to-nearest mode,
116 * this can't happen; instead, the absolute value of each r[j] will
117 * be less than 1/2 the least significant bit corresponding to r[j-1],
118 * so that the entire remainder must be at least half as large as
119 * the first nonzero term (or perhaps just barely smaller than this).
120 */
121
122 #include <sys/isa_defs.h>
123
124 #ifdef _LITTLE_ENDIAN
125 #define HIWORD 1
126 #define LOWORD 0
127 #else
128 #define HIWORD 0
129 #define LOWORD 1
130 #endif
131
132 /* 396 hex digits of 2/pi, with two leading zeroes to make life easier */
133 static const double ipio2[] = {
134 0, 0,
135 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
136 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
137 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
138 0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
139 0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
140 0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
141 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
142 0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
143 0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
144 0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
145 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
146 };
147
148 /* pi/2 in 24-bit pieces */
149 static const double pio2[] = {
150 1.57079625129699707031e+00,
151 7.54978941586159635335e-08,
152 5.39030252995776476554e-15,
153 3.28200341580791294123e-22,
154 1.27065575308067607349e-29,
155 };
156
157 /* miscellaneous constants */
158 static const double
159 zero = 0.0,
160 two24 = 16777216.0,
161 round1 = 6755399441055744.0, /* 3 * 2^51 */
162 round24 = 113336795588871485128704.0, /* 3 * 2^75 */
163 twon24 = 5.960464477539062500E-8;
164
165 int
__vlibm_rem_pio2m(double * x,double * y,int e,int nx,int prec)166 __vlibm_rem_pio2m(double *x, double *y, int e, int nx, int prec)
167 {
168 union {
169 double d;
170 int i[2];
171 } s;
172 double z, t, p, q[20], r[21], *pr;
173 int nq, ip, n, i, j, k, eq0, eqnqm1;
174
175 /* determine ip and eq0; note that -48 <= eq0 <= 2 */
176 ip = (e - 3) / 24;
177 if (ip < 0)
178 ip = 0;
179 eq0 = e - 24 * (ip + 1);
180
181 /* compute q[0,...,5] = x * ipio2 and initialize nq and eqnqm1 */
182 if (nx == 3) {
183 q[0] = x[0] * ipio2[ip+2] + x[1] * ipio2[ip+1] + x[2] * ipio2[ip];
184 q[1] = x[0] * ipio2[ip+3] + x[1] * ipio2[ip+2] + x[2] * ipio2[ip+1];
185 q[2] = x[0] * ipio2[ip+4] + x[1] * ipio2[ip+3] + x[2] * ipio2[ip+2];
186 q[3] = x[0] * ipio2[ip+5] + x[1] * ipio2[ip+4] + x[2] * ipio2[ip+3];
187 q[4] = x[0] * ipio2[ip+6] + x[1] * ipio2[ip+5] + x[2] * ipio2[ip+4];
188 q[5] = x[0] * ipio2[ip+7] + x[1] * ipio2[ip+6] + x[2] * ipio2[ip+5];
189 } else if (nx == 2) {
190 q[0] = x[0] * ipio2[ip+2] + x[1] * ipio2[ip+1];
191 q[1] = x[0] * ipio2[ip+3] + x[1] * ipio2[ip+2];
192 q[2] = x[0] * ipio2[ip+4] + x[1] * ipio2[ip+3];
193 q[3] = x[0] * ipio2[ip+5] + x[1] * ipio2[ip+4];
194 q[4] = x[0] * ipio2[ip+6] + x[1] * ipio2[ip+5];
195 q[5] = x[0] * ipio2[ip+7] + x[1] * ipio2[ip+6];
196 } else {
197 q[0] = x[0] * ipio2[ip+2];
198 q[1] = x[0] * ipio2[ip+3];
199 q[2] = x[0] * ipio2[ip+4];
200 q[3] = x[0] * ipio2[ip+5];
201 q[4] = x[0] * ipio2[ip+6];
202 q[5] = x[0] * ipio2[ip+7];
203 }
204 nq = 5;
205 eqnqm1 = eq0 - 96;
206
207 recompute:
208 /* propagate carries and incorporate powers of two */
209 s.i[HIWORD] = (0x3ff + eqnqm1) << 20;
210 s.i[LOWORD] = 0;
211 p = s.d;
212 z = q[nq] * twon24;
213 for (j = nq-1; j >= 1; j--) {
214 z += q[j];
215 t = (z + round24) - round24; /* must be rounded to nearest */
216 r[j+1] = (z - t) * p;
217 z = t * twon24;
218 p *= two24;
219 }
220 z += q[0];
221 t = (z + round24) - round24; /* must be rounded to nearest */
222 r[1] = (z - t) * p;
223 r[0] = t * p;
224
225 /* form n = [r] mod 8 and leave the fractional part of r */
226 if (eq0 > 0) {
227 /* binary point lies within r[2] */
228 z = r[2] + r[3];
229 t = (z + round1) - round1; /* must be rounded to nearest */
230 r[2] -= t;
231 n = (int)(r[1] + t);
232 r[0] = r[1] = zero;
233 } else if (eq0 > -24) {
234 /* binary point lies within or just to the right of r[1] */
235 z = r[1] + r[2];
236 t = (z + round1) - round1; /* must be rounded to nearest */
237 r[1] -= t;
238 z = r[0] + t;
239 /* cut off high part of z so conversion to int doesn't
240 overflow */
241 t = (z + round24) - round24;
242 n = (int)(z - t);
243 r[0] = zero;
244 } else {
245 /* binary point lies within or just to the right of r[0] */
246 z = r[0] + r[1];
247 t = (z + round1) - round1; /* must be rounded to nearest */
248 r[0] -= t;
249 n = (int)t;
250 }
251
252 /* count the number of leading zeroes in r */
253 for (j = 0; j <= nq; j++) {
254 if (r[j] != zero)
255 break;
256 }
257
258 /* if fewer than 5 terms remain, add more */
259 if (nq - j < 4) {
260 k = 4 - (nq - j);
261 /*
262 * compute q[nq+1] to q[nq+k]
263 *
264 * For some reason, writing out the nx loop explicitly
265 * for each of the three possible values (as above) seems
266 * to run a little slower, so we'll leave this code as is.
267 */
268 for (i = nq + 1; i <= nq + k; i++) {
269 t = x[0] * ipio2[ip+2+i];
270 for (j = 1; j < nx; j++)
271 t += x[j] * ipio2[ip+2+i-j];
272 q[i] = t;
273 eqnqm1 -= 24;
274 }
275 nq += k;
276 goto recompute;
277 }
278
279 /* set pr and nq so that pr[0,...,nq] is the part of r remaining */
280 pr = &r[j];
281 nq = nq - j;
282
283 /* compute pio2 * pr[0,...,nq]; note that nq >= 4 here */
284 q[0] = pio2[0] * pr[0];
285 q[1] = pio2[0] * pr[1] + pio2[1] * pr[0];
286 q[2] = pio2[0] * pr[2] + pio2[1] * pr[1] + pio2[2] * pr[0];
287 q[3] = pio2[0] * pr[3] + pio2[1] * pr[2] + pio2[2] * pr[1]
288 + pio2[3] * pr[0];
289 for (i = 4; i <= nq; i++) {
290 q[i] = pio2[0] * pr[i] + pio2[1] * pr[i-1] + pio2[2] * pr[i-2]
291 + pio2[3] * pr[i-3] + pio2[4] * pr[i-4];
292 }
293
294 /* sum q in increasing order to obtain the first term of y */
295 t = q[nq];
296 for (i = nq - 1; i >= 0; i--)
297 t += q[i];
298 y[0] = t;
299 if (prec) {
300 /* subtract and sum again in decreasing order
301 to obtain the second term */
302 t = q[0] - t;
303 for (i = 1; i <= nq; i++)
304 t += q[i];
305 y[1] = t;
306 }
307
308 return (n & 7);
309 }
310