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 #pragma weak __sqrtl = sqrtl
31
32 #include "libm.h"
33 #include "longdouble.h"
34
35 extern int __swapTE(int);
36 extern int __swapEX(int);
37 extern enum fp_direction_type __swapRD(enum fp_direction_type);
38
39 /*
40 * in struct longdouble, msw consists of
41 * unsigned short sgn:1;
42 * unsigned short exp:15;
43 * unsigned short frac1:16;
44 */
45
46 #ifdef __LITTLE_ENDIAN
47
48 /* array indices used to access words within a double */
49 #define HIWORD 1
50 #define LOWORD 0
51
52 /* structure used to access words within a quad */
53 union longdouble {
54 struct {
55 unsigned int frac4;
56 unsigned int frac3;
57 unsigned int frac2;
58 unsigned int msw;
59 } l;
60 long double d;
61 };
62
63 /* default NaN returned for sqrt(neg) */
64 static const union longdouble
65 qnan = { 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff };
66
67 /* signalling NaN used to raise invalid */
68 static const union {
69 unsigned u[2];
70 double d;
71 } snan = { 0, 0x7ff00001 };
72
73 #else
74
75 /* array indices used to access words within a double */
76 #define HIWORD 0
77 #define LOWORD 1
78
79 /* structure used to access words within a quad */
80 union longdouble {
81 struct {
82 unsigned int msw;
83 unsigned int frac2;
84 unsigned int frac3;
85 unsigned int frac4;
86 } l;
87 long double d;
88 };
89
90 /* default NaN returned for sqrt(neg) */
91 static const union longdouble
92 qnan = { 0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff };
93
94 /* signalling NaN used to raise invalid */
95 static const union {
96 unsigned u[2];
97 double d;
98 } snan = { 0x7ff00001, 0 };
99
100 #endif /* __LITTLE_ENDIAN */
101
102
103 static const double
104 zero = 0.0,
105 half = 0.5,
106 one = 1.0,
107 huge = 1.0e300,
108 tiny = 1.0e-300,
109 two36 = 6.87194767360000000000e+10,
110 two30 = 1.07374182400000000000e+09,
111 two6 = 6.40000000000000000000e+01,
112 two4 = 1.60000000000000000000e+01,
113 twom18 = 3.81469726562500000000e-06,
114 twom28 = 3.72529029846191406250e-09,
115 twom42 = 2.27373675443232059479e-13,
116 twom60 = 8.67361737988403547206e-19,
117 twom62 = 2.16840434497100886801e-19,
118 twom66 = 1.35525271560688054251e-20,
119 twom90 = 8.07793566946316088742e-28,
120 twom113 = 9.62964972193617926528e-35,
121 twom124 = 4.70197740328915003187e-38;
122
123
124 /*
125 * Extract the exponent and normalized significand (represented as
126 * an array of five doubles) from a finite, nonzero quad.
127 */
128 static int
129 __q_unpack(const union longdouble *x, double *s)
130 {
131 union {
132 double d;
133 unsigned int l[2];
134 } u;
135 double b;
136 unsigned int lx, w[3];
137 int ex;
138
139 /* get the normalized significand and exponent */
140 ex = (int) ((x->l.msw & 0x7fffffff) >> 16);
141 lx = x->l.msw & 0xffff;
142 if (ex)
143 {
144 lx |= 0x10000;
145 w[0] = x->l.frac2;
146 w[1] = x->l.frac3;
147 w[2] = x->l.frac4;
148 }
149 else
150 {
151 if (lx | (x->l.frac2 & 0xfffe0000))
152 {
153 w[0] = x->l.frac2;
154 w[1] = x->l.frac3;
155 w[2] = x->l.frac4;
156 ex = 1;
157 }
158 else if (x->l.frac2 | (x->l.frac3 & 0xfffe0000))
159 {
160 lx = x->l.frac2;
161 w[0] = x->l.frac3;
162 w[1] = x->l.frac4;
163 w[2] = 0;
164 ex = -31;
165 }
166 else if (x->l.frac3 | (x->l.frac4 & 0xfffe0000))
167 {
168 lx = x->l.frac3;
169 w[0] = x->l.frac4;
170 w[1] = w[2] = 0;
171 ex = -63;
172 }
173 else
174 {
175 lx = x->l.frac4;
176 w[0] = w[1] = w[2] = 0;
177 ex = -95;
178 }
179 while ((lx & 0x10000) == 0)
180 {
181 lx = (lx << 1) | (w[0] >> 31);
182 w[0] = (w[0] << 1) | (w[1] >> 31);
183 w[1] = (w[1] << 1) | (w[2] >> 31);
184 w[2] <<= 1;
185 ex--;
186 }
187 }
188
189 /* extract the significand into five doubles */
190 u.l[HIWORD] = 0x42300000;
191 u.l[LOWORD] = 0;
192 b = u.d;
193 u.l[LOWORD] = lx;
194 s[0] = u.d - b;
195
196 u.l[HIWORD] = 0x40300000;
197 u.l[LOWORD] = 0;
198 b = u.d;
199 u.l[LOWORD] = w[0] & 0xffffff00;
200 s[1] = u.d - b;
202 u.l[HIWORD] = 0x3e300000;
203 u.l[LOWORD] = 0;
204 b = u.d;
205 u.l[HIWORD] |= w[0] & 0xff;
206 u.l[LOWORD] = w[1] & 0xffff0000;
207 s[2] = u.d - b;
208
209 u.l[HIWORD] = 0x3c300000;
210 u.l[LOWORD] = 0;
211 b = u.d;
212 u.l[HIWORD] |= w[1] & 0xffff;
213 u.l[LOWORD] = w[2] & 0xff000000;
214 s[3] = u.d - b;
215
216 u.l[HIWORD] = 0x3c300000;
217 u.l[LOWORD] = 0;
218 b = u.d;
219 u.l[LOWORD] = w[2] & 0xffffff;
220 s[4] = u.d - b;
221
222 return ex - 0x3fff;
223 }
224
225
226 /*
227 * Pack an exponent and array of three doubles representing a finite,
228 * nonzero number into a quad. Assume the sign is already there and
229 * the rounding mode has been fudged accordingly.
230 */
231 static void
232 __q_pack(const double *z, int exp, enum fp_direction_type rm,
233 union longdouble *x, int *inexact)
234 {
235 union {
236 double d;
237 unsigned int l[2];
238 } u;
239 double s[3], t, t2;
240 unsigned int msw, frac2, frac3, frac4;
241
242 /* bias exponent and strip off integer bit */
243 exp += 0x3fff;
244 s[0] = z[0] - one;
245 s[1] = z[1];
246 s[2] = z[2];
247
248 /*
249 * chop the significand to obtain the fraction;
250 * use round-to-minus-infinity to ensure chopping
251 */
252 (void) __swapRD(fp_negative);
253
254 /* extract the first eighty bits of fraction */
255 t = s[1] + s[2];
256 u.d = two36 + (s[0] + t);
257 msw = u.l[LOWORD];
258 s[0] -= (u.d - two36);
265 frac3 = u.l[LOWORD];
266 s[0] -= (u.d - twom28);
267
268 /* condense the remaining fraction; errors here won't matter */
269 t = s[0] + s[1];
270 s[1] = ((s[0] - t) + s[1]) + s[2];
271 s[0] = t;
272
273 /* get the last word of fraction */
274 u.d = twom60 + (s[0] + s[1]);
275 frac4 = u.l[LOWORD];
276 s[0] -= (u.d - twom60);
277
278 /*
279 * keep track of what's left for rounding; note that
280 * t2 will be non-negative due to rounding mode
281 */
282 t = s[0] + s[1];
283 t2 = (s[0] - t) + s[1];
284
285 if (t != zero)
286 {
287 *inexact = 1;
288
289 /* decide whether to round the fraction up */
290 if (rm == fp_positive || (rm == fp_nearest && (t > twom113 ||
291 (t == twom113 && (t2 != zero || frac4 & 1)))))
292 {
293 /* round up and renormalize if necessary */
294 if (++frac4 == 0)
295 if (++frac3 == 0)
296 if (++frac2 == 0)
297 if (++msw == 0x10000)
298 {
299 msw = 0;
300 exp++;
301 }
302 }
303 }
304
305 /* assemble the result */
306 x->l.msw |= msw | (exp << 16);
307 x->l.frac2 = frac2;
308 x->l.frac3 = frac3;
309 x->l.frac4 = frac4;
310 }
311
312
313 /*
314 * Compute the square root of x and place the TP result in s.
315 */
316 static void
317 __q_tp_sqrt(const double *x, double *s)
318 {
319 double c, rr, r[3], tt[3], t[5];
320
321 /* approximate the divisor for the Newton iteration */
322 c = sqrt((x[0] + x[1]) + x[2]);
323 rr = half / c;
324
325 /* compute the first five "digits" of the square root */
326 t[0] = (c + two30) - two30;
327 tt[0] = t[0] + t[0];
328 r[0] = ((x[0] - t[0] * t[0]) + x[1]) + x[2];
329
330 t[1] = (rr * (r[0] + x[3]) + two6) - two6;
331 tt[1] = t[1] + t[1];
332 r[0] -= tt[0] * t[1];
333 r[1] = x[3] - t[1] * t[1];
334 c = (r[1] + twom18) - twom18;
335 r[0] += c;
336 r[1] = (r[1] - c) + x[4];
337
338 t[2] = (rr * (r[0] + r[1]) + twom18) - twom18;
339 tt[2] = t[2] + t[2];
340 r[0] -= tt[0] * t[2];
341 r[1] -= tt[1] * t[2];
342 c = (r[1] + twom42) - twom42;
343 r[0] += c;
344 r[1] = (r[1] - c) - t[2] * t[2];
345
346 t[3] = (rr * (r[0] + r[1]) + twom42) - twom42;
347 r[0] = ((r[0] - tt[0] * t[3]) + r[1]) - tt[1] * t[3];
348 r[1] = -tt[2] * t[3];
349 c = (r[1] + twom90) - twom90;
350 r[0] += c;
351 r[1] = (r[1] - c) - t[3] * t[3];
352
353 t[4] = (rr * (r[0] + r[1]) + twom66) - twom66;
354
355 /* here we just need to get the sign of the remainder */
356 c = (((((r[0] - tt[0] * t[4]) - tt[1] * t[4]) + r[1])
357 - tt[2] * t[4]) - (t[3] + t[3]) * t[4]) - t[4] * t[4];
358
359 /* reduce to three doubles */
360 t[0] += t[1];
361 t[1] = t[2] + t[3];
362 t[2] = t[4];
363
364 /* if the third term might lie on a rounding boundary, perturb it */
365 if (c != zero && t[2] == (twom62 + t[2]) - twom62)
366 {
367 if (c < zero)
368 t[2] -= twom124;
369 else
370 t[2] += twom124;
371 }
372
373 /* condense the square root */
374 c = t[1] + t[2];
375 t[2] += (t[1] - c);
376 t[1] = c;
377 c = t[0] + t[1];
378 s[1] = t[1] + (t[0] - c);
379 s[0] = c;
380 if (s[1] == zero)
381 {
382 c = s[0] + t[2];
383 s[1] = t[2] + (s[0] - c);
384 s[0] = c;
385 s[2] = zero;
386 }
387 else
388 {
389 c = s[1] + t[2];
390 s[2] = t[2] + (s[1] - c);
391 s[1] = c;
392 }
393 }
394
395
396 long double
397 sqrtl(long double ldx)
398 {
399 union longdouble x;
400 volatile double t;
401 double xx[5], zz[3];
402 enum fp_direction_type rm;
403 int ex, inexact, exc, traps;
404
405 /* clear cexc */
406 t = zero;
407 t -= zero;
408
409 /* check for zero operand */
410 x.d = ldx;
411 if (!((x.l.msw & 0x7fffffff) | x.l.frac2 | x.l.frac3 | x.l.frac4))
412 return ldx;
413
414 /* handle nan and inf cases */
415 if ((x.l.msw & 0x7fffffff) >= 0x7fff0000)
416 {
417 if ((x.l.msw & 0xffff) | x.l.frac2 | x.l.frac3 | x.l.frac4)
418 {
419 if (!(x.l.msw & 0x8000))
420 {
421 /* snan, signal invalid */
422 t += snan.d;
423 }
424 x.l.msw |= 0x8000;
425 return x.d;
426 }
427 if (x.l.msw & 0x80000000)
428 {
429 /* sqrt(-inf), signal invalid */
430 t = -one;
431 t = sqrt(t);
432 return qnan.d;
433 }
434 /* sqrt(inf), return inf */
435 return x.d;
436 }
437
438 /* handle negative numbers */
439 if (x.l.msw & 0x80000000)
440 {
441 t = -one;
442 t = sqrt(t);
443 return qnan.d;
444 }
445
446 /* now x is finite, positive */
447
448 traps = __swapTE(0);
449 exc = __swapEX(0);
450 rm = __swapRD(fp_nearest);
451
452 ex = __q_unpack(&x, xx);
453 if (ex & 1)
454 {
455 /* make exponent even */
456 xx[0] += xx[0];
457 xx[1] += xx[1];
458 xx[2] += xx[2];
459 xx[3] += xx[3];
460 xx[4] += xx[4];
461 ex--;
462 }
463 __q_tp_sqrt(xx, zz);
464
465 /* put everything together */
466 x.l.msw = 0;
467 inexact = 0;
468 __q_pack(zz, ex >> 1, rm, &x, &inexact);
469
470 (void) __swapRD(rm);
471 (void) __swapEX(exc);
472 (void) __swapTE(traps);
473 if (inexact)
474 {
475 t = huge;
476 t += tiny;
477 }
478 return x.d;
479 }
|
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 /*
27 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 #pragma weak __sqrtl = sqrtl
32
33 #include "libm.h"
34 #include "longdouble.h"
35
36 extern int __swapTE(int);
37 extern int __swapEX(int);
38 extern enum fp_direction_type __swapRD(enum fp_direction_type);
39
40 /*
41 * in struct longdouble, msw consists of
42 * unsigned short sgn:1;
43 * unsigned short exp:15;
44 * unsigned short frac1:16;
45 */
46
47 #ifdef __LITTLE_ENDIAN
48 /* array indices used to access words within a double */
49 #define HIWORD 1
50 #define LOWORD 0
51
52 /* structure used to access words within a quad */
53 union longdouble {
54 struct {
55 unsigned int frac4;
56 unsigned int frac3;
57 unsigned int frac2;
58 unsigned int msw;
59 } l;
60 long double d;
61 };
62
63 /* default NaN returned for sqrt(neg) */
64 static const union longdouble qnan = {
65 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff
66 };
67
68 /* signalling NaN used to raise invalid */
69 static const union {
70 unsigned u[2];
71 double d;
72 } snan = { 0, 0x7ff00001 };
73 #else
74 /* array indices used to access words within a double */
75 #define HIWORD 0
76 #define LOWORD 1
77
78 /* structure used to access words within a quad */
79 union longdouble {
80 struct {
81 unsigned int msw;
82 unsigned int frac2;
83 unsigned int frac3;
84 unsigned int frac4;
85 } l;
86 long double d;
87 };
88
89 /* default NaN returned for sqrt(neg) */
90 static const union longdouble qnan = {
91 0x7fffffff, 0xffffffff, 0xffffffff, 0xffffffff
92 };
93
94 /* signalling NaN used to raise invalid */
95 static const union {
96 unsigned u[2];
97 double d;
98 } snan = { 0x7ff00001, 0 };
99 #endif /* __LITTLE_ENDIAN */
100
101 static const double zero = 0.0,
102 half = 0.5,
103 one = 1.0,
104 huge = 1.0e300,
105 tiny = 1.0e-300,
106 two36 = 6.87194767360000000000e+10,
107 two30 = 1.07374182400000000000e+09,
108 two6 = 6.40000000000000000000e+01,
109 two4 = 1.60000000000000000000e+01,
110 twom18 = 3.81469726562500000000e-06,
111 twom28 = 3.72529029846191406250e-09,
112 twom42 = 2.27373675443232059479e-13,
113 twom60 = 8.67361737988403547206e-19,
114 twom62 = 2.16840434497100886801e-19,
115 twom66 = 1.35525271560688054251e-20,
116 twom90 = 8.07793566946316088742e-28,
117 twom113 = 9.62964972193617926528e-35,
118 twom124 = 4.70197740328915003187e-38;
119
120 /*
121 * Extract the exponent and normalized significand (represented as
122 * an array of five doubles) from a finite, nonzero quad.
123 */
124 static int
125 __q_unpack(const union longdouble *x, double *s)
126 {
127 union {
128 double d;
129 unsigned int l[2];
130 } u;
131
132 double b;
133 unsigned int lx, w[3];
134 int ex;
135
136 /* get the normalized significand and exponent */
137 ex = (int)((x->l.msw & 0x7fffffff) >> 16);
138 lx = x->l.msw & 0xffff;
139
140 if (ex) {
141 lx |= 0x10000;
142 w[0] = x->l.frac2;
143 w[1] = x->l.frac3;
144 w[2] = x->l.frac4;
145 } else {
146 if (lx | (x->l.frac2 & 0xfffe0000)) {
147 w[0] = x->l.frac2;
148 w[1] = x->l.frac3;
149 w[2] = x->l.frac4;
150 ex = 1;
151 } else if (x->l.frac2 | (x->l.frac3 & 0xfffe0000)) {
152 lx = x->l.frac2;
153 w[0] = x->l.frac3;
154 w[1] = x->l.frac4;
155 w[2] = 0;
156 ex = -31;
157 } else if (x->l.frac3 | (x->l.frac4 & 0xfffe0000)) {
158 lx = x->l.frac3;
159 w[0] = x->l.frac4;
160 w[1] = w[2] = 0;
161 ex = -63;
162 } else {
163 lx = x->l.frac4;
164 w[0] = w[1] = w[2] = 0;
165 ex = -95;
166 }
167
168 while ((lx & 0x10000) == 0) {
169 lx = (lx << 1) | (w[0] >> 31);
170 w[0] = (w[0] << 1) | (w[1] >> 31);
171 w[1] = (w[1] << 1) | (w[2] >> 31);
172 w[2] <<= 1;
173 ex--;
174 }
175 }
176
177 /* extract the significand into five doubles */
178 u.l[HIWORD] = 0x42300000;
179 u.l[LOWORD] = 0;
180 b = u.d;
181 u.l[LOWORD] = lx;
182 s[0] = u.d - b;
183
184 u.l[HIWORD] = 0x40300000;
185 u.l[LOWORD] = 0;
186 b = u.d;
187 u.l[LOWORD] = w[0] & 0xffffff00;
188 s[1] = u.d - b;
190 u.l[HIWORD] = 0x3e300000;
191 u.l[LOWORD] = 0;
192 b = u.d;
193 u.l[HIWORD] |= w[0] & 0xff;
194 u.l[LOWORD] = w[1] & 0xffff0000;
195 s[2] = u.d - b;
196
197 u.l[HIWORD] = 0x3c300000;
198 u.l[LOWORD] = 0;
199 b = u.d;
200 u.l[HIWORD] |= w[1] & 0xffff;
201 u.l[LOWORD] = w[2] & 0xff000000;
202 s[3] = u.d - b;
203
204 u.l[HIWORD] = 0x3c300000;
205 u.l[LOWORD] = 0;
206 b = u.d;
207 u.l[LOWORD] = w[2] & 0xffffff;
208 s[4] = u.d - b;
209
210 return (ex - 0x3fff);
211 }
212
213 /*
214 * Pack an exponent and array of three doubles representing a finite,
215 * nonzero number into a quad. Assume the sign is already there and
216 * the rounding mode has been fudged accordingly.
217 */
218 static void
219 __q_pack(const double *z, int exp, enum fp_direction_type rm,
220 union longdouble *x, int *inexact)
221 {
222 union {
223 double d;
224 unsigned int l[2];
225 } u;
226
227 double s[3], t, t2;
228 unsigned int msw, frac2, frac3, frac4;
229
230 /* bias exponent and strip off integer bit */
231 exp += 0x3fff;
232 s[0] = z[0] - one;
233 s[1] = z[1];
234 s[2] = z[2];
235
236 /*
237 * chop the significand to obtain the fraction;
238 * use round-to-minus-infinity to ensure chopping
239 */
240 (void) __swapRD(fp_negative);
241
242 /* extract the first eighty bits of fraction */
243 t = s[1] + s[2];
244 u.d = two36 + (s[0] + t);
245 msw = u.l[LOWORD];
246 s[0] -= (u.d - two36);
253 frac3 = u.l[LOWORD];
254 s[0] -= (u.d - twom28);
255
256 /* condense the remaining fraction; errors here won't matter */
257 t = s[0] + s[1];
258 s[1] = ((s[0] - t) + s[1]) + s[2];
259 s[0] = t;
260
261 /* get the last word of fraction */
262 u.d = twom60 + (s[0] + s[1]);
263 frac4 = u.l[LOWORD];
264 s[0] -= (u.d - twom60);
265
266 /*
267 * keep track of what's left for rounding; note that
268 * t2 will be non-negative due to rounding mode
269 */
270 t = s[0] + s[1];
271 t2 = (s[0] - t) + s[1];
272
273 if (t != zero) {
274 *inexact = 1;
275
276 /* decide whether to round the fraction up */
277 if (rm == fp_positive || (rm == fp_nearest && (t > twom113 ||
278 (t == twom113 && (t2 != zero || frac4 & 1))))) {
279 /* round up and renormalize if necessary */
280 if (++frac4 == 0) {
281 if (++frac3 == 0) {
282 if (++frac2 == 0) {
283 if (++msw == 0x10000) {
284 msw = 0;
285 exp++;
286 }
287 }
288 }
289 }
290 }
291 }
292
293 /* assemble the result */
294 x->l.msw |= msw | (exp << 16);
295 x->l.frac2 = frac2;
296 x->l.frac3 = frac3;
297 x->l.frac4 = frac4;
298 }
299
300 /*
301 * Compute the square root of x and place the TP result in s.
302 */
303 static void
304 __q_tp_sqrt(const double *x, double *s)
305 {
306 double c, rr, r[3], tt[3], t[5];
307
308 /* approximate the divisor for the Newton iteration */
309 c = sqrt((x[0] + x[1]) + x[2]);
310 rr = half / c;
311
312 /* compute the first five "digits" of the square root */
313 t[0] = (c + two30) - two30;
314 tt[0] = t[0] + t[0];
315 r[0] = ((x[0] - t[0] * t[0]) + x[1]) + x[2];
316
317 t[1] = (rr * (r[0] + x[3]) + two6) - two6;
318 tt[1] = t[1] + t[1];
319 r[0] -= tt[0] * t[1];
320 r[1] = x[3] - t[1] * t[1];
321 c = (r[1] + twom18) - twom18;
322 r[0] += c;
323 r[1] = (r[1] - c) + x[4];
324
325 t[2] = (rr * (r[0] + r[1]) + twom18) - twom18;
326 tt[2] = t[2] + t[2];
327 r[0] -= tt[0] * t[2];
328 r[1] -= tt[1] * t[2];
329 c = (r[1] + twom42) - twom42;
330 r[0] += c;
331 r[1] = (r[1] - c) - t[2] * t[2];
332
333 t[3] = (rr * (r[0] + r[1]) + twom42) - twom42;
334 r[0] = ((r[0] - tt[0] * t[3]) + r[1]) - tt[1] * t[3];
335 r[1] = -tt[2] * t[3];
336 c = (r[1] + twom90) - twom90;
337 r[0] += c;
338 r[1] = (r[1] - c) - t[3] * t[3];
339
340 t[4] = (rr * (r[0] + r[1]) + twom66) - twom66;
341
342 /* here we just need to get the sign of the remainder */
343 c = (((((r[0] - tt[0] * t[4]) - tt[1] * t[4]) + r[1]) - tt[2] * t[4]) -
344 (t[3] + t[3]) * t[4]) - t[4] * t[4];
345
346 /* reduce to three doubles */
347 t[0] += t[1];
348 t[1] = t[2] + t[3];
349 t[2] = t[4];
350
351 /* if the third term might lie on a rounding boundary, perturb it */
352 if (c != zero && t[2] == (twom62 + t[2]) - twom62) {
353 if (c < zero)
354 t[2] -= twom124;
355 else
356 t[2] += twom124;
357 }
358
359 /* condense the square root */
360 c = t[1] + t[2];
361 t[2] += (t[1] - c);
362 t[1] = c;
363 c = t[0] + t[1];
364 s[1] = t[1] + (t[0] - c);
365 s[0] = c;
366
367 if (s[1] == zero) {
368 c = s[0] + t[2];
369 s[1] = t[2] + (s[0] - c);
370 s[0] = c;
371 s[2] = zero;
372 } else {
373 c = s[1] + t[2];
374 s[2] = t[2] + (s[1] - c);
375 s[1] = c;
376 }
377 }
378
379 long double
380 sqrtl(long double ldx)
381 {
382 union longdouble x;
383 volatile double t;
384 double xx[5], zz[3];
385 enum fp_direction_type rm;
386 int ex, inexact, exc, traps;
387
388 /* clear cexc */
389 t = zero;
390 t -= zero;
391
392 /* check for zero operand */
393 x.d = ldx;
394
395 if (!((x.l.msw & 0x7fffffff) | x.l.frac2 | x.l.frac3 | x.l.frac4))
396 return (ldx);
397
398 /* handle nan and inf cases */
399 if ((x.l.msw & 0x7fffffff) >= 0x7fff0000) {
400 if ((x.l.msw & 0xffff) | x.l.frac2 | x.l.frac3 | x.l.frac4) {
401 if (!(x.l.msw & 0x8000)) {
402 /* snan, signal invalid */
403 t += snan.d;
404 }
405
406 x.l.msw |= 0x8000;
407 return (x.d);
408 }
409
410 if (x.l.msw & 0x80000000) {
411 /* sqrt(-inf), signal invalid */
412 t = -one;
413 t = sqrt(t);
414 return (qnan.d);
415 }
416
417 /* sqrt(inf), return inf */
418 return (x.d);
419 }
420
421 /* handle negative numbers */
422 if (x.l.msw & 0x80000000) {
423 t = -one;
424 t = sqrt(t);
425 return (qnan.d);
426 }
427
428 /* now x is finite, positive */
429
430 traps = __swapTE(0);
431 exc = __swapEX(0);
432 rm = __swapRD(fp_nearest);
433
434 ex = __q_unpack(&x, xx);
435
436 if (ex & 1) {
437 /* make exponent even */
438 xx[0] += xx[0];
439 xx[1] += xx[1];
440 xx[2] += xx[2];
441 xx[3] += xx[3];
442 xx[4] += xx[4];
443 ex--;
444 }
445
446 __q_tp_sqrt(xx, zz);
447
448 /* put everything together */
449 x.l.msw = 0;
450 inexact = 0;
451 __q_pack(zz, ex >> 1, rm, &x, &inexact);
452
453 (void) __swapRD(rm);
454 (void) __swapEX(exc);
455 (void) __swapTE(traps);
456
457 if (inexact) {
458 t = huge;
459 t += tiny;
460 }
461
462 return (x.d);
463 }
|