1*25c28e83SPiotr Jasiukajtis /* 2*25c28e83SPiotr Jasiukajtis * CDDL HEADER START 3*25c28e83SPiotr Jasiukajtis * 4*25c28e83SPiotr Jasiukajtis * The contents of this file are subject to the terms of the 5*25c28e83SPiotr Jasiukajtis * Common Development and Distribution License (the "License"). 6*25c28e83SPiotr Jasiukajtis * You may not use this file except in compliance with the License. 7*25c28e83SPiotr Jasiukajtis * 8*25c28e83SPiotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*25c28e83SPiotr Jasiukajtis * or http://www.opensolaris.org/os/licensing. 10*25c28e83SPiotr Jasiukajtis * See the License for the specific language governing permissions 11*25c28e83SPiotr Jasiukajtis * and limitations under the License. 12*25c28e83SPiotr Jasiukajtis * 13*25c28e83SPiotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each 14*25c28e83SPiotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*25c28e83SPiotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the 16*25c28e83SPiotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying 17*25c28e83SPiotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner] 18*25c28e83SPiotr Jasiukajtis * 19*25c28e83SPiotr Jasiukajtis * CDDL HEADER END 20*25c28e83SPiotr Jasiukajtis */ 21*25c28e83SPiotr Jasiukajtis 22*25c28e83SPiotr Jasiukajtis /* 23*25c28e83SPiotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 24*25c28e83SPiotr Jasiukajtis */ 25*25c28e83SPiotr Jasiukajtis /* 26*25c28e83SPiotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 27*25c28e83SPiotr Jasiukajtis * Use is subject to license terms. 28*25c28e83SPiotr Jasiukajtis */ 29*25c28e83SPiotr Jasiukajtis 30*25c28e83SPiotr Jasiukajtis /* INDENT OFF */ 31*25c28e83SPiotr Jasiukajtis /* 32*25c28e83SPiotr Jasiukajtis * void sincospi(double x, double *s, double *c) 33*25c28e83SPiotr Jasiukajtis * *s = sin(pi*x); *c = cos(pi*x); 34*25c28e83SPiotr Jasiukajtis * 35*25c28e83SPiotr Jasiukajtis * Algorithm, 10/17/2002, K.C. Ng 36*25c28e83SPiotr Jasiukajtis * ------------------------------ 37*25c28e83SPiotr Jasiukajtis * Let y = |4x|, z = floor(y), and n = (int)(z mod 8.0) (displayed in binary). 38*25c28e83SPiotr Jasiukajtis * 1. If y == z, then x is a multiple of pi/4. Return the following values: 39*25c28e83SPiotr Jasiukajtis * --------------------------------------------------- 40*25c28e83SPiotr Jasiukajtis * n x mod 2 sin(x*pi) cos(x*pi) tan(x*pi) 41*25c28e83SPiotr Jasiukajtis * --------------------------------------------------- 42*25c28e83SPiotr Jasiukajtis * 000 0.00 +0 ___ +1 ___ +0 43*25c28e83SPiotr Jasiukajtis * 001 0.25 +\/0.5 +\/0.5 +1 44*25c28e83SPiotr Jasiukajtis * 010 0.50 +1 ___ +0 ___ +inf 45*25c28e83SPiotr Jasiukajtis * 011 0.75 +\/0.5 -\/0.5 -1 46*25c28e83SPiotr Jasiukajtis * 100 1.00 -0 ___ -1 ___ +0 47*25c28e83SPiotr Jasiukajtis * 101 1.25 -\/0.5 -\/0.5 +1 48*25c28e83SPiotr Jasiukajtis * 110 1.50 -1 ___ -0 ___ +inf 49*25c28e83SPiotr Jasiukajtis * 111 1.75 -\/0.5 +\/0.5 -1 50*25c28e83SPiotr Jasiukajtis * --------------------------------------------------- 51*25c28e83SPiotr Jasiukajtis * 2. Otherwise, 52*25c28e83SPiotr Jasiukajtis * --------------------------------------------------- 53*25c28e83SPiotr Jasiukajtis * n t sin(x*pi) cos(x*pi) tan(x*pi) 54*25c28e83SPiotr Jasiukajtis * --------------------------------------------------- 55*25c28e83SPiotr Jasiukajtis * 000 (y-z)/4 sinpi(t) cospi(t) tanpi(t) 56*25c28e83SPiotr Jasiukajtis * 001 (z+1-y)/4 cospi(t) sinpi(t) 1/tanpi(t) 57*25c28e83SPiotr Jasiukajtis * 010 (y-z)/4 cospi(t) -sinpi(t) -1/tanpi(t) 58*25c28e83SPiotr Jasiukajtis * 011 (z+1-y)/4 sinpi(t) -cospi(t) -tanpi(t) 59*25c28e83SPiotr Jasiukajtis * 100 (y-z)/4 -sinpi(t) -cospi(t) tanpi(t) 60*25c28e83SPiotr Jasiukajtis * 101 (z+1-y)/4 -cospi(t) -sinpi(t) 1/tanpi(t) 61*25c28e83SPiotr Jasiukajtis * 110 (y-z)/4 -cospi(t) sinpi(t) -1/tanpi(t) 62*25c28e83SPiotr Jasiukajtis * 111 (z+1-y)/4 -sinpi(t) cospi(t) -tanpi(t) 63*25c28e83SPiotr Jasiukajtis * --------------------------------------------------- 64*25c28e83SPiotr Jasiukajtis * 65*25c28e83SPiotr Jasiukajtis * NOTE. This program compute sinpi/cospi(t<0.25) by __k_sin/cos(pi*t, 0.0). 66*25c28e83SPiotr Jasiukajtis * This will return a result with error slightly more than one ulp (but less 67*25c28e83SPiotr Jasiukajtis * than 2 ulp). If one wants accurate result, one may break up pi*t in 68*25c28e83SPiotr Jasiukajtis * high (tpi_h) and low (tpi_l) parts and call __k_sin/cos(tip_h, tip_lo) 69*25c28e83SPiotr Jasiukajtis * instead. 70*25c28e83SPiotr Jasiukajtis */ 71*25c28e83SPiotr Jasiukajtis 72*25c28e83SPiotr Jasiukajtis #include "libm.h" 73*25c28e83SPiotr Jasiukajtis #include "libm_protos.h" 74*25c28e83SPiotr Jasiukajtis #include "libm_macros.h" 75*25c28e83SPiotr Jasiukajtis #include <math.h> 76*25c28e83SPiotr Jasiukajtis #if defined(__SUNPRO_C) 77*25c28e83SPiotr Jasiukajtis #include <sunmath.h> 78*25c28e83SPiotr Jasiukajtis #endif 79*25c28e83SPiotr Jasiukajtis 80*25c28e83SPiotr Jasiukajtis static const double 81*25c28e83SPiotr Jasiukajtis pi = 3.14159265358979323846, /* 400921FB,54442D18 */ 82*25c28e83SPiotr Jasiukajtis sqrth_h = 0.70710678118654757273731092936941422522068023681640625, 83*25c28e83SPiotr Jasiukajtis sqrth_l = -4.8336466567264565185935844299127932213411660131004e-17; 84*25c28e83SPiotr Jasiukajtis /* INDENT ON */ 85*25c28e83SPiotr Jasiukajtis 86*25c28e83SPiotr Jasiukajtis void 87*25c28e83SPiotr Jasiukajtis sincospi(double x, double *s, double *c) { 88*25c28e83SPiotr Jasiukajtis double y, z, t; 89*25c28e83SPiotr Jasiukajtis int n, ix, k; 90*25c28e83SPiotr Jasiukajtis int hx = ((int *) &x)[HIWORD]; 91*25c28e83SPiotr Jasiukajtis unsigned h, lx = ((unsigned *) &x)[LOWORD]; 92*25c28e83SPiotr Jasiukajtis 93*25c28e83SPiotr Jasiukajtis ix = hx & ~0x80000000; 94*25c28e83SPiotr Jasiukajtis n = (ix >> 20) - 0x3ff; 95*25c28e83SPiotr Jasiukajtis if (n >= 51) { /* |x| >= 2**51 */ 96*25c28e83SPiotr Jasiukajtis if (n >= 1024) 97*25c28e83SPiotr Jasiukajtis #if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) 98*25c28e83SPiotr Jasiukajtis *s = *c = ix >= 0x7ff80000 ? x : x - x; 99*25c28e83SPiotr Jasiukajtis /* assumes sparc-like QNaN */ 100*25c28e83SPiotr Jasiukajtis #else 101*25c28e83SPiotr Jasiukajtis *s = *c = x - x; 102*25c28e83SPiotr Jasiukajtis #endif 103*25c28e83SPiotr Jasiukajtis else { 104*25c28e83SPiotr Jasiukajtis if (n >= 53) { 105*25c28e83SPiotr Jasiukajtis *s = 0.0; 106*25c28e83SPiotr Jasiukajtis *c = 1.0; 107*25c28e83SPiotr Jasiukajtis } 108*25c28e83SPiotr Jasiukajtis else if (n == 52) { 109*25c28e83SPiotr Jasiukajtis if ((lx & 1) == 0) { 110*25c28e83SPiotr Jasiukajtis *s = 0.0; 111*25c28e83SPiotr Jasiukajtis *c = 1.0; 112*25c28e83SPiotr Jasiukajtis } 113*25c28e83SPiotr Jasiukajtis else { 114*25c28e83SPiotr Jasiukajtis *s = -0.0; 115*25c28e83SPiotr Jasiukajtis *c = -1.0; 116*25c28e83SPiotr Jasiukajtis } 117*25c28e83SPiotr Jasiukajtis } 118*25c28e83SPiotr Jasiukajtis else { /* n == 51 */ 119*25c28e83SPiotr Jasiukajtis if ((lx & 1) == 0) { 120*25c28e83SPiotr Jasiukajtis *s = 0.0; 121*25c28e83SPiotr Jasiukajtis *c = 1.0; 122*25c28e83SPiotr Jasiukajtis } 123*25c28e83SPiotr Jasiukajtis else { 124*25c28e83SPiotr Jasiukajtis *s = 1.0; 125*25c28e83SPiotr Jasiukajtis *c = 0.0; 126*25c28e83SPiotr Jasiukajtis } 127*25c28e83SPiotr Jasiukajtis if ((lx & 2) != 0) { 128*25c28e83SPiotr Jasiukajtis *s = -*s; 129*25c28e83SPiotr Jasiukajtis *c = -*c; 130*25c28e83SPiotr Jasiukajtis } 131*25c28e83SPiotr Jasiukajtis } 132*25c28e83SPiotr Jasiukajtis } 133*25c28e83SPiotr Jasiukajtis } 134*25c28e83SPiotr Jasiukajtis else if (n < -2) /* |x| < 0.25 */ 135*25c28e83SPiotr Jasiukajtis *s = __k_sincos(pi * fabs(x), 0.0, c); 136*25c28e83SPiotr Jasiukajtis else { 137*25c28e83SPiotr Jasiukajtis /* y = |4x|, z = floor(y), and n = (int)(z mod 8.0) */ 138*25c28e83SPiotr Jasiukajtis if (ix < 0x41C00000) { /* |x| < 2**29 */ 139*25c28e83SPiotr Jasiukajtis y = 4.0 * fabs(x); 140*25c28e83SPiotr Jasiukajtis n = (int) y; /* exact */ 141*25c28e83SPiotr Jasiukajtis z = (double) n; 142*25c28e83SPiotr Jasiukajtis k = z == y; 143*25c28e83SPiotr Jasiukajtis t = (y - z) * 0.25; 144*25c28e83SPiotr Jasiukajtis } 145*25c28e83SPiotr Jasiukajtis else { /* 2**29 <= |x| < 2**51 */ 146*25c28e83SPiotr Jasiukajtis y = fabs(x); 147*25c28e83SPiotr Jasiukajtis k = 50 - n; 148*25c28e83SPiotr Jasiukajtis n = lx >> k; 149*25c28e83SPiotr Jasiukajtis h = n << k; 150*25c28e83SPiotr Jasiukajtis ((unsigned *) &z)[LOWORD] = h; 151*25c28e83SPiotr Jasiukajtis ((int *) &z)[HIWORD] = ix; 152*25c28e83SPiotr Jasiukajtis k = h == lx; 153*25c28e83SPiotr Jasiukajtis t = y - z; 154*25c28e83SPiotr Jasiukajtis } 155*25c28e83SPiotr Jasiukajtis if (k) { /* x = N/4 */ 156*25c28e83SPiotr Jasiukajtis if ((n & 1) != 0) 157*25c28e83SPiotr Jasiukajtis *s = *c = sqrth_h + sqrth_l; 158*25c28e83SPiotr Jasiukajtis else 159*25c28e83SPiotr Jasiukajtis if ((n & 2) == 0) { 160*25c28e83SPiotr Jasiukajtis *s = 0.0; 161*25c28e83SPiotr Jasiukajtis *c = 1.0; 162*25c28e83SPiotr Jasiukajtis } 163*25c28e83SPiotr Jasiukajtis else { 164*25c28e83SPiotr Jasiukajtis *s = 1.0; 165*25c28e83SPiotr Jasiukajtis *c = 0.0; 166*25c28e83SPiotr Jasiukajtis } 167*25c28e83SPiotr Jasiukajtis y = (n & 2) == 0 ? 0.0 : 1.0; 168*25c28e83SPiotr Jasiukajtis if ((n & 4) != 0) 169*25c28e83SPiotr Jasiukajtis *s = -*s; 170*25c28e83SPiotr Jasiukajtis if (((n + 1) & 4) != 0) 171*25c28e83SPiotr Jasiukajtis *c = -*c; 172*25c28e83SPiotr Jasiukajtis } 173*25c28e83SPiotr Jasiukajtis else { 174*25c28e83SPiotr Jasiukajtis if ((n & 1) != 0) 175*25c28e83SPiotr Jasiukajtis t = 0.25 - t; 176*25c28e83SPiotr Jasiukajtis if (((n + (n & 1)) & 2) == 0) 177*25c28e83SPiotr Jasiukajtis *s = __k_sincos(pi * t, 0.0, c); 178*25c28e83SPiotr Jasiukajtis else 179*25c28e83SPiotr Jasiukajtis *c = __k_sincos(pi * t, 0.0, s); 180*25c28e83SPiotr Jasiukajtis if ((n & 4) != 0) 181*25c28e83SPiotr Jasiukajtis *s = -*s; 182*25c28e83SPiotr Jasiukajtis if (((n + 2) & 4) != 0) 183*25c28e83SPiotr Jasiukajtis *c = -*c; 184*25c28e83SPiotr Jasiukajtis } 185*25c28e83SPiotr Jasiukajtis } 186*25c28e83SPiotr Jasiukajtis if (hx < 0) 187*25c28e83SPiotr Jasiukajtis *s = -*s; 188*25c28e83SPiotr Jasiukajtis } 189