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 /* 27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * __rem_pio2(x, y) passes back a better-than-double-precision 33 * approximation to x mod pi/2 in y[0]+y[1] and returns an integer 34 * congruent mod 8 to the integer part of x/(pi/2). 35 * 36 * This implementation tacitly assumes that x is finite and at 37 * least about pi/4 in magnitude. 38 */ 39 40 #include "libm.h" 41 42 extern const int _TBL_ipio2_inf[]; 43 44 45 /* 46 * invpio2: 53 bits of 2/pi 47 * pio2_1: first 33 bit of pi/2 48 * pio2_1t: pi/2 - pio2_1 49 * pio2_2: second 33 bit of pi/2 50 * pio2_2t: pi/2 - pio2_2 51 * pio2_3: third 33 bit of pi/2 52 * pio2_3t: pi/2 - pio2_3 53 */ 54 static const double half = 0.5, 55 invpio2 = 0.636619772367581343075535, /* 2^ -1 * 1.45F306DC9C883 */ 56 pio2_1 = 1.570796326734125614166, /* 2^ 0 * 1.921FB54400000 */ 57 pio2_1t = 6.077100506506192601475e-11, /* 2^-34 * 1.0B4611A626331 */ 58 pio2_2 = 6.077100506303965976596e-11, /* 2^-34 * 1.0B4611A600000 */ 59 pio2_2t = 2.022266248795950732400e-21, /* 2^-69 * 1.3198A2E037073 */ 60 pio2_3 = 2.022266248711166455796e-21, /* 2^-69 * 1.3198A2E000000 */ 61 pio2_3t = 8.478427660368899643959e-32; /* 2^-104 * 1.B839A252049C1 */ 62 63 64 int 65 __rem_pio2(double x, double *y) 66 { 67 double w, t, r, fn; 68 double tx[3]; 69 int e0, i, j, nx, n, ix, hx, lx; 70 71 hx = ((int *)&x)[HIWORD]; 72 ix = hx & 0x7fffffff; 73 74 if (ix < 0x4002d97c) { 75 /* |x| < 3pi/4, special case with n=1 */ 76 t = fabs(x) - pio2_1; 77 78 if (ix != 0x3ff921fb) { /* 33+53 bit pi is good enough */ 79 y[0] = t - pio2_1t; 80 y[1] = (t - y[0]) - pio2_1t; 81 } else { /* near pi/2, use 33+33+53 bit pi */ 82 t -= pio2_2; 83 y[0] = t - pio2_2t; 84 y[1] = (t - y[0]) - pio2_2t; 85 } 86 87 if (hx < 0) { 88 y[0] = -y[0]; 89 y[1] = -y[1]; 90 return (-1); 91 } 92 93 return (1); 94 } 95 96 if (ix <= 0x413921fb) { 97 /* |x| <= 2^19 pi */ 98 t = fabs(x); 99 n = (int)(t * invpio2 + half); 100 fn = (double)n; 101 r = t - fn * pio2_1; 102 j = ix >> 20; 103 w = fn * pio2_1t; /* 1st round good to 85 bit */ 104 y[0] = r - w; 105 i = j - ((((int *)y)[HIWORD] >> 20) & 0x7ff); 106 107 if (i > 16) { /* 2nd iteration (rare) */ 108 /* 2nd round good to 118 bit */ 109 if (i < 35) { 110 t = r; /* r-fn*pio2_2 may not be exact */ 111 w = fn * pio2_2; 112 r = t - w; 113 w = fn * pio2_2t - ((t - r) - w); 114 y[0] = r - w; 115 } else { 116 r -= fn * pio2_2; 117 w = fn * pio2_2t; 118 y[0] = r - w; 119 i = j - ((((int *)y)[HIWORD] >> 20) & 0x7ff); 120 121 if (i > 49) { 122 /* 3rd iteration (extremely rare) */ 123 if (i < 68) { 124 t = r; 125 w = fn * pio2_3; 126 r = t - w; 127 w = fn * pio2_3t - ((t - r) - 128 w); 129 y[0] = r - w; 130 } else { 131 /* 132 * 3rd round good to 151 bits; 133 * covered all possible cases 134 */ 135 r -= fn * pio2_3; 136 w = fn * pio2_3t; 137 y[0] = r - w; 138 } 139 } 140 } 141 } 142 143 y[1] = (r - y[0]) - w; 144 145 if (hx < 0) { 146 y[0] = -y[0]; 147 y[1] = -y[1]; 148 return (-n); 149 } 150 151 return (n); 152 } 153 154 e0 = (ix >> 20) - 1046; /* e0 = ilogb(x)-23; */ 155 156 /* break x into three 24 bit pieces */ 157 lx = ((int *)&x)[LOWORD]; 158 i = (lx & 0x1f) << 19; 159 tx[2] = (double)i; 160 j = (lx >> 5) & 0xffffff; 161 tx[1] = (double)j; 162 tx[0] = (double)((((ix & 0xfffff) | 0x100000) << 3) | ((unsigned)lx >> 163 29)); 164 nx = 3; 165 166 if (i == 0) { 167 /* skip zero term */ 168 nx--; 169 170 if (j == 0) 171 nx--; 172 } 173 174 n = __rem_pio2m(tx, y, e0, nx, 2, _TBL_ipio2_inf); 175 176 if (hx < 0) { 177 y[0] = -y[0]; 178 y[1] = -y[1]; 179 return (-n); 180 } 181 182 return (n); 183 }