1*e1b98d07SMichal Meloun /*- 2*e1b98d07SMichal Meloun * Copyright (c) 2007, 2010-2013 Steven G. Kargl 3*e1b98d07SMichal Meloun * All rights reserved. 4*e1b98d07SMichal Meloun * 5*e1b98d07SMichal Meloun * Redistribution and use in source and binary forms, with or without 6*e1b98d07SMichal Meloun * modification, are permitted provided that the following conditions 7*e1b98d07SMichal Meloun * are met: 8*e1b98d07SMichal Meloun * 1. Redistributions of source code must retain the above copyright 9*e1b98d07SMichal Meloun * notice unmodified, this list of conditions, and the following 10*e1b98d07SMichal Meloun * disclaimer. 11*e1b98d07SMichal Meloun * 2. Redistributions in binary form must reproduce the above copyright 12*e1b98d07SMichal Meloun * notice, this list of conditions and the following disclaimer in the 13*e1b98d07SMichal Meloun * documentation and/or other materials provided with the distribution. 14*e1b98d07SMichal Meloun * 15*e1b98d07SMichal Meloun * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16*e1b98d07SMichal Meloun * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17*e1b98d07SMichal Meloun * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18*e1b98d07SMichal Meloun * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19*e1b98d07SMichal Meloun * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20*e1b98d07SMichal Meloun * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21*e1b98d07SMichal Meloun * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22*e1b98d07SMichal Meloun * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23*e1b98d07SMichal Meloun * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24*e1b98d07SMichal Meloun * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25*e1b98d07SMichal Meloun * 26*e1b98d07SMichal Meloun * s_sinl.c and s_cosl.c merged by Steven G. Kargl. 27*e1b98d07SMichal Meloun */ 28*e1b98d07SMichal Meloun 29*e1b98d07SMichal Meloun #include <sys/cdefs.h> 30*e1b98d07SMichal Meloun __FBSDID("$FreeBSD$"); 31*e1b98d07SMichal Meloun 32*e1b98d07SMichal Meloun #include <float.h> 33*e1b98d07SMichal Meloun #ifdef __i386__ 34*e1b98d07SMichal Meloun #include <ieeefp.h> 35*e1b98d07SMichal Meloun #endif 36*e1b98d07SMichal Meloun 37*e1b98d07SMichal Meloun #include "math.h" 38*e1b98d07SMichal Meloun #include "math_private.h" 39*e1b98d07SMichal Meloun #include "k_sincosl.h" 40*e1b98d07SMichal Meloun 41*e1b98d07SMichal Meloun #if LDBL_MANT_DIG == 64 42*e1b98d07SMichal Meloun #include "../ld80/e_rem_pio2l.h" 43*e1b98d07SMichal Meloun #elif LDBL_MANT_DIG == 113 44*e1b98d07SMichal Meloun #include "../ld128/e_rem_pio2l.h" 45*e1b98d07SMichal Meloun #else 46*e1b98d07SMichal Meloun #error "Unsupported long double format" 47*e1b98d07SMichal Meloun #endif 48*e1b98d07SMichal Meloun 49*e1b98d07SMichal Meloun void 50*e1b98d07SMichal Meloun sincosl(long double x, long double *sn, long double *cs) 51*e1b98d07SMichal Meloun { 52*e1b98d07SMichal Meloun union IEEEl2bits z; 53*e1b98d07SMichal Meloun int e0, sgn; 54*e1b98d07SMichal Meloun long double y[2]; 55*e1b98d07SMichal Meloun 56*e1b98d07SMichal Meloun z.e = x; 57*e1b98d07SMichal Meloun sgn = z.bits.sign; 58*e1b98d07SMichal Meloun z.bits.sign = 0; 59*e1b98d07SMichal Meloun 60*e1b98d07SMichal Meloun ENTERV(); 61*e1b98d07SMichal Meloun 62*e1b98d07SMichal Meloun /* Optimize the case where x is already within range. */ 63*e1b98d07SMichal Meloun if (z.e < M_PI_4) { 64*e1b98d07SMichal Meloun /* 65*e1b98d07SMichal Meloun * If x = +-0 or x is a subnormal number, then sin(x) = x and 66*e1b98d07SMichal Meloun * cos(x) = 1. 67*e1b98d07SMichal Meloun */ 68*e1b98d07SMichal Meloun if (z.bits.exp == 0) { 69*e1b98d07SMichal Meloun *sn = x; 70*e1b98d07SMichal Meloun *cs = 1; 71*e1b98d07SMichal Meloun } else 72*e1b98d07SMichal Meloun __kernel_sincosl(x, 0, 0, sn, cs); 73*e1b98d07SMichal Meloun RETURNV(); 74*e1b98d07SMichal Meloun } 75*e1b98d07SMichal Meloun 76*e1b98d07SMichal Meloun /* If x = NaN or Inf, then sin(x) and cos(x) are NaN. */ 77*e1b98d07SMichal Meloun if (z.bits.exp == 32767) { 78*e1b98d07SMichal Meloun *sn = x - x; 79*e1b98d07SMichal Meloun *cs = x - x; 80*e1b98d07SMichal Meloun RETURNV(); 81*e1b98d07SMichal Meloun } 82*e1b98d07SMichal Meloun 83*e1b98d07SMichal Meloun /* Range reduction. */ 84*e1b98d07SMichal Meloun e0 = __ieee754_rem_pio2l(x, y); 85*e1b98d07SMichal Meloun 86*e1b98d07SMichal Meloun switch (e0 & 3) { 87*e1b98d07SMichal Meloun case 0: 88*e1b98d07SMichal Meloun __kernel_sincosl(y[0], y[1], 1, sn, cs); 89*e1b98d07SMichal Meloun break; 90*e1b98d07SMichal Meloun case 1: 91*e1b98d07SMichal Meloun __kernel_sincosl(y[0], y[1], 1, cs, sn); 92*e1b98d07SMichal Meloun *cs = -*cs; 93*e1b98d07SMichal Meloun break; 94*e1b98d07SMichal Meloun case 2: 95*e1b98d07SMichal Meloun __kernel_sincosl(y[0], y[1], 1, sn, cs); 96*e1b98d07SMichal Meloun *sn = -*sn; 97*e1b98d07SMichal Meloun *cs = -*cs; 98*e1b98d07SMichal Meloun break; 99*e1b98d07SMichal Meloun default: 100*e1b98d07SMichal Meloun __kernel_sincosl(y[0], y[1], 1, cs, sn); 101*e1b98d07SMichal Meloun *sn = -*sn; 102*e1b98d07SMichal Meloun } 103*e1b98d07SMichal Meloun 104*e1b98d07SMichal Meloun RETURNV(); 105*e1b98d07SMichal Meloun } 106