15b2ba9d3SPiotr Jasiukajtis /*
25b2ba9d3SPiotr Jasiukajtis * CDDL HEADER START
35b2ba9d3SPiotr Jasiukajtis *
45b2ba9d3SPiotr Jasiukajtis * The contents of this file are subject to the terms of the
55b2ba9d3SPiotr Jasiukajtis * Common Development and Distribution License (the "License").
65b2ba9d3SPiotr Jasiukajtis * You may not use this file except in compliance with the License.
75b2ba9d3SPiotr Jasiukajtis *
85b2ba9d3SPiotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95b2ba9d3SPiotr Jasiukajtis * or http://www.opensolaris.org/os/licensing.
105b2ba9d3SPiotr Jasiukajtis * See the License for the specific language governing permissions
115b2ba9d3SPiotr Jasiukajtis * and limitations under the License.
125b2ba9d3SPiotr Jasiukajtis *
135b2ba9d3SPiotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each
145b2ba9d3SPiotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155b2ba9d3SPiotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the
165b2ba9d3SPiotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying
175b2ba9d3SPiotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner]
185b2ba9d3SPiotr Jasiukajtis *
195b2ba9d3SPiotr Jasiukajtis * CDDL HEADER END
205b2ba9d3SPiotr Jasiukajtis */
215b2ba9d3SPiotr Jasiukajtis /*
225b2ba9d3SPiotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
235b2ba9d3SPiotr Jasiukajtis */
245b2ba9d3SPiotr Jasiukajtis /*
255b2ba9d3SPiotr Jasiukajtis * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
265b2ba9d3SPiotr Jasiukajtis * Use is subject to license terms.
275b2ba9d3SPiotr Jasiukajtis */
285b2ba9d3SPiotr Jasiukajtis
29*a9d3dcd5SRichard Lowe #pragma weak __sin = sin
305b2ba9d3SPiotr Jasiukajtis
315b2ba9d3SPiotr Jasiukajtis /* INDENT OFF */
325b2ba9d3SPiotr Jasiukajtis /*
335b2ba9d3SPiotr Jasiukajtis * sin(x)
345b2ba9d3SPiotr Jasiukajtis * Accurate Table look-up algorithm by K.C. Ng, May, 1995.
355b2ba9d3SPiotr Jasiukajtis *
365b2ba9d3SPiotr Jasiukajtis * Algorithm: see sincos.c
375b2ba9d3SPiotr Jasiukajtis */
385b2ba9d3SPiotr Jasiukajtis
395b2ba9d3SPiotr Jasiukajtis #include "libm.h"
405b2ba9d3SPiotr Jasiukajtis
415b2ba9d3SPiotr Jasiukajtis static const double sc[] = {
425b2ba9d3SPiotr Jasiukajtis /* ONE = */ 1.0,
435b2ba9d3SPiotr Jasiukajtis /* NONE = */ -1.0,
445b2ba9d3SPiotr Jasiukajtis /*
455b2ba9d3SPiotr Jasiukajtis * |sin(x) - (x+pp1*x^3+pp2*x^5)| <= 2^-58.79 for |x| < 0.008
465b2ba9d3SPiotr Jasiukajtis */
475b2ba9d3SPiotr Jasiukajtis /* PP1 = */ -0.166666666666316558867252052378889521480627858683055567,
485b2ba9d3SPiotr Jasiukajtis /* PP2 = */ .008333315652997472323564894248466758248475374977974017927,
495b2ba9d3SPiotr Jasiukajtis /*
505b2ba9d3SPiotr Jasiukajtis * |(sin(x) - (x+p1*x^3+...+p4*x^9)|
515b2ba9d3SPiotr Jasiukajtis * |------------------------------ | <= 2^-57.63 for |x| < 0.1953125
525b2ba9d3SPiotr Jasiukajtis * | x |
535b2ba9d3SPiotr Jasiukajtis */
545b2ba9d3SPiotr Jasiukajtis /* P1 = */ -1.666666666666629669805215138920301589656e-0001,
555b2ba9d3SPiotr Jasiukajtis /* P2 = */ 8.333333332390951295683993455280336376663e-0003,
565b2ba9d3SPiotr Jasiukajtis /* P3 = */ -1.984126237997976692791551778230098403960e-0004,
575b2ba9d3SPiotr Jasiukajtis /* P4 = */ 2.753403624854277237649987622848330351110e-0006,
585b2ba9d3SPiotr Jasiukajtis /*
595b2ba9d3SPiotr Jasiukajtis * |cos(x) - (1+qq1*x^2+qq2*x^4)| <= 2^-55.99 for |x| <= 0.008 (0x3f80624d)
605b2ba9d3SPiotr Jasiukajtis */
615b2ba9d3SPiotr Jasiukajtis /* QQ1 = */ -0.4999999999975492381842911981948418542742729,
625b2ba9d3SPiotr Jasiukajtis /* QQ2 = */ 0.041666542904352059294545209158357640398771740,
635b2ba9d3SPiotr Jasiukajtis /* PI_H = */ 3.1415926535897931159979634685,
645b2ba9d3SPiotr Jasiukajtis /* PI_L = */ 1.22464679914735317722606593227425e-16,
655b2ba9d3SPiotr Jasiukajtis /* PI_L0 = */ 1.22464679914558443311283879205095e-16,
665b2ba9d3SPiotr Jasiukajtis /* PI_L1 = */ 1.768744113227140223300005233735517376e-28,
675b2ba9d3SPiotr Jasiukajtis /* PI2_H = */ 6.2831853071795862319959269370,
685b2ba9d3SPiotr Jasiukajtis /* PI2_L = */ 2.44929359829470635445213186454850e-16,
695b2ba9d3SPiotr Jasiukajtis /* PI2_L0 = */ 2.44929359829116886622567758410190e-16,
705b2ba9d3SPiotr Jasiukajtis /* PI2_L1 = */ 3.537488226454280446600010467471034752e-28,
715b2ba9d3SPiotr Jasiukajtis };
725b2ba9d3SPiotr Jasiukajtis /* INDENT ON */
735b2ba9d3SPiotr Jasiukajtis
745b2ba9d3SPiotr Jasiukajtis #define ONEA sc
755b2ba9d3SPiotr Jasiukajtis #define ONE sc[0]
765b2ba9d3SPiotr Jasiukajtis #define NONE sc[1]
775b2ba9d3SPiotr Jasiukajtis #define PP1 sc[2]
785b2ba9d3SPiotr Jasiukajtis #define PP2 sc[3]
795b2ba9d3SPiotr Jasiukajtis #define P1 sc[4]
805b2ba9d3SPiotr Jasiukajtis #define P2 sc[5]
815b2ba9d3SPiotr Jasiukajtis #define P3 sc[6]
825b2ba9d3SPiotr Jasiukajtis #define P4 sc[7]
835b2ba9d3SPiotr Jasiukajtis #define QQ1 sc[8]
845b2ba9d3SPiotr Jasiukajtis #define QQ2 sc[9]
855b2ba9d3SPiotr Jasiukajtis #define PI_H sc[10]
865b2ba9d3SPiotr Jasiukajtis #define PI_L sc[11]
875b2ba9d3SPiotr Jasiukajtis #define PI_L0 sc[12]
885b2ba9d3SPiotr Jasiukajtis #define PI_L1 sc[13]
895b2ba9d3SPiotr Jasiukajtis #define PI2_H sc[14]
905b2ba9d3SPiotr Jasiukajtis #define PI2_L sc[15]
915b2ba9d3SPiotr Jasiukajtis #define PI2_L0 sc[16]
925b2ba9d3SPiotr Jasiukajtis #define PI2_L1 sc[17]
935b2ba9d3SPiotr Jasiukajtis
945b2ba9d3SPiotr Jasiukajtis extern const double _TBL_sincos[], _TBL_sincosx[];
955b2ba9d3SPiotr Jasiukajtis
965b2ba9d3SPiotr Jasiukajtis double
sin(double x)975b2ba9d3SPiotr Jasiukajtis sin(double x) {
985b2ba9d3SPiotr Jasiukajtis double z, y[2], w, s, v, p, q;
995b2ba9d3SPiotr Jasiukajtis int i, j, n, hx, ix, lx;
1005b2ba9d3SPiotr Jasiukajtis
1015b2ba9d3SPiotr Jasiukajtis hx = ((int *)&x)[HIWORD];
1025b2ba9d3SPiotr Jasiukajtis lx = ((int *)&x)[LOWORD];
1035b2ba9d3SPiotr Jasiukajtis ix = hx & ~0x80000000;
1045b2ba9d3SPiotr Jasiukajtis
1055b2ba9d3SPiotr Jasiukajtis if (ix <= 0x3fc50000) { /* |x| < .1640625 */
1065b2ba9d3SPiotr Jasiukajtis if (ix < 0x3e400000) /* |x| < 2**-27 */
1075b2ba9d3SPiotr Jasiukajtis if ((int)x == 0)
1085b2ba9d3SPiotr Jasiukajtis return (x);
1095b2ba9d3SPiotr Jasiukajtis z = x * x;
1105b2ba9d3SPiotr Jasiukajtis if (ix < 0x3f800000) /* |x| < 2**-8 */
1115b2ba9d3SPiotr Jasiukajtis w = (z * x) * (PP1 + z * PP2);
1125b2ba9d3SPiotr Jasiukajtis else
1135b2ba9d3SPiotr Jasiukajtis w = (x * z) * ((P1 + z * P2) + (z * z) * (P3 + z * P4));
1145b2ba9d3SPiotr Jasiukajtis return (x + w);
1155b2ba9d3SPiotr Jasiukajtis }
1165b2ba9d3SPiotr Jasiukajtis
1175b2ba9d3SPiotr Jasiukajtis /* for .1640625 < x < M, */
1185b2ba9d3SPiotr Jasiukajtis n = ix >> 20;
1195b2ba9d3SPiotr Jasiukajtis if (n < 0x402) { /* x < 8 */
1205b2ba9d3SPiotr Jasiukajtis i = (((ix >> 12) & 0xff) | 0x100) >> (0x401 - n);
1215b2ba9d3SPiotr Jasiukajtis j = i - 10;
1225b2ba9d3SPiotr Jasiukajtis x = fabs(x);
1235b2ba9d3SPiotr Jasiukajtis v = x - _TBL_sincosx[j];
1245b2ba9d3SPiotr Jasiukajtis if (((j - 181) ^ (j - 201)) < 0) {
1255b2ba9d3SPiotr Jasiukajtis /* near pi, sin(x) = sin(pi-x) */
1265b2ba9d3SPiotr Jasiukajtis p = PI_H - x;
1275b2ba9d3SPiotr Jasiukajtis i = ix - 0x400921fb;
1285b2ba9d3SPiotr Jasiukajtis x = p + PI_L;
1295b2ba9d3SPiotr Jasiukajtis if ((i | ((lx - 0x54442D00) & 0xffffff00)) == 0) {
1305b2ba9d3SPiotr Jasiukajtis /* very close to pi */
1315b2ba9d3SPiotr Jasiukajtis x = p + PI_L0;
1325b2ba9d3SPiotr Jasiukajtis return ((hx >= 0)? x + PI_L1 : -(x + PI_L1));
1335b2ba9d3SPiotr Jasiukajtis }
1345b2ba9d3SPiotr Jasiukajtis z = x * x;
1355b2ba9d3SPiotr Jasiukajtis if (((ix - 0x40092000) >> 11) == 0) {
1365b2ba9d3SPiotr Jasiukajtis /* |pi-x|<2**-8 */
1375b2ba9d3SPiotr Jasiukajtis w = PI_L + (z * x) * (PP1 + z * PP2);
1385b2ba9d3SPiotr Jasiukajtis } else {
1395b2ba9d3SPiotr Jasiukajtis w = PI_L + (z * x) * ((P1 + z * P2) +
1405b2ba9d3SPiotr Jasiukajtis (z * z) * (P3 + z * P4));
1415b2ba9d3SPiotr Jasiukajtis }
1425b2ba9d3SPiotr Jasiukajtis return ((hx >= 0)? p + w : -p - w);
1435b2ba9d3SPiotr Jasiukajtis }
1445b2ba9d3SPiotr Jasiukajtis s = v * v;
1455b2ba9d3SPiotr Jasiukajtis if (((j - 382) ^ (j - 402)) < 0) {
1465b2ba9d3SPiotr Jasiukajtis /* near 2pi, sin(x) = sin(x-2pi) */
1475b2ba9d3SPiotr Jasiukajtis p = x - PI2_H;
1485b2ba9d3SPiotr Jasiukajtis i = ix - 0x401921fb;
1495b2ba9d3SPiotr Jasiukajtis x = p - PI2_L;
1505b2ba9d3SPiotr Jasiukajtis if ((i | ((lx - 0x54442D00) & 0xffffff00)) == 0) {
1515b2ba9d3SPiotr Jasiukajtis /* very close to 2pi */
1525b2ba9d3SPiotr Jasiukajtis x = p - PI2_L0;
1535b2ba9d3SPiotr Jasiukajtis return ((hx >= 0)? x - PI2_L1 : -(x - PI2_L1));
1545b2ba9d3SPiotr Jasiukajtis }
1555b2ba9d3SPiotr Jasiukajtis z = x * x;
1565b2ba9d3SPiotr Jasiukajtis if (((ix - 0x40192000) >> 10) == 0) {
1575b2ba9d3SPiotr Jasiukajtis /* |x-2pi|<2**-8 */
1585b2ba9d3SPiotr Jasiukajtis w = (z * x) * (PP1 + z * PP2) - PI2_L;
1595b2ba9d3SPiotr Jasiukajtis } else {
1605b2ba9d3SPiotr Jasiukajtis w = (z * x) * ((P1 + z * P2) +
1615b2ba9d3SPiotr Jasiukajtis (z * z) * (P3 + z * P4)) - PI2_L;
1625b2ba9d3SPiotr Jasiukajtis }
1635b2ba9d3SPiotr Jasiukajtis return ((hx >= 0)? p + w : -p - w);
1645b2ba9d3SPiotr Jasiukajtis }
1655b2ba9d3SPiotr Jasiukajtis j <<= 1;
1665b2ba9d3SPiotr Jasiukajtis w = _TBL_sincos[j+1];
1675b2ba9d3SPiotr Jasiukajtis z = _TBL_sincos[j];
1685b2ba9d3SPiotr Jasiukajtis p = v + (v * s) * (PP1 + s * PP2);
1695b2ba9d3SPiotr Jasiukajtis q = s * (QQ1 + s * QQ2);
1705b2ba9d3SPiotr Jasiukajtis v = w * p + z * q;
1715b2ba9d3SPiotr Jasiukajtis return ((hx >= 0)? z + v : -z - v);
1725b2ba9d3SPiotr Jasiukajtis }
1735b2ba9d3SPiotr Jasiukajtis
1745b2ba9d3SPiotr Jasiukajtis if (ix >= 0x7ff00000) /* sin(Inf or NaN) is NaN */
1755b2ba9d3SPiotr Jasiukajtis return (x / x);
1765b2ba9d3SPiotr Jasiukajtis
1775b2ba9d3SPiotr Jasiukajtis /* argument reduction needed */
1785b2ba9d3SPiotr Jasiukajtis n = __rem_pio2(x, y);
1795b2ba9d3SPiotr Jasiukajtis switch (n & 3) {
1805b2ba9d3SPiotr Jasiukajtis case 0:
1815b2ba9d3SPiotr Jasiukajtis return (__k_sin(y[0], y[1]));
1825b2ba9d3SPiotr Jasiukajtis case 1:
1835b2ba9d3SPiotr Jasiukajtis return (__k_cos(y[0], y[1]));
1845b2ba9d3SPiotr Jasiukajtis case 2:
1855b2ba9d3SPiotr Jasiukajtis return (-__k_sin(y[0], y[1]));
1865b2ba9d3SPiotr Jasiukajtis default:
1875b2ba9d3SPiotr Jasiukajtis return (-__k_cos(y[0], y[1]));
1885b2ba9d3SPiotr Jasiukajtis }
1895b2ba9d3SPiotr Jasiukajtis }
190