1 1.1 christos /* From: @(#)e_rem_pio2.c 1.4 95/01/18 */ 2 1.1 christos /* 3 1.1 christos * ==================================================== 4 1.1 christos * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 5 1.1 christos * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans. 6 1.1 christos * 7 1.1 christos * Developed at SunSoft, a Sun Microsystems, Inc. business. 8 1.1 christos * Permission to use, copy, modify, and distribute this 9 1.2 riastrad * software is freely granted, provided that this notice 10 1.1 christos * is preserved. 11 1.1 christos * ==================================================== 12 1.1 christos * 13 1.1 christos * Optimized by Bruce D. Evans. 14 1.1 christos */ 15 1.1 christos 16 1.1 christos #include <sys/cdefs.h> 17 1.1 christos #if 0 18 1.1 christos __FBSDID("$FreeBSD: head/lib/msun/ld128/e_rem_pio2l.h 336545 2018-07-20 12:42:24Z bde $"); 19 1.1 christos #endif 20 1.1 christos 21 1.1 christos /* ld128 version of __ieee754_rem_pio2l(x,y) 22 1.2 riastrad * 23 1.2 riastrad * return the remainder of x rem pi/2 in y[0]+y[1] 24 1.1 christos * use __kernel_rem_pio2() 25 1.1 christos */ 26 1.1 christos 27 1.1 christos #include <float.h> 28 1.1 christos #include <machine/ieee.h> 29 1.1 christos 30 1.1 christos #include "math.h" 31 1.1 christos #include "math_private.h" 32 1.1 christos 33 1.1 christos #define BIAS (LDBL_MAX_EXP - 1) 34 1.1 christos 35 1.1 christos /* 36 1.1 christos * XXX need to verify that nonzero integer multiples of pi/2 within the 37 1.1 christos * range get no closer to a long double than 2**-140, or that 38 1.1 christos * ilogb(x) + ilogb(min_delta) < 45 - -140. 39 1.1 christos */ 40 1.1 christos /* 41 1.1 christos * invpio2: 113 bits of 2/pi 42 1.1 christos * pio2_1: first 68 bits of pi/2 43 1.1 christos * pio2_1t: pi/2 - pio2_1 44 1.1 christos * pio2_2: second 68 bits of pi/2 45 1.1 christos * pio2_2t: pi/2 - (pio2_1+pio2_2) 46 1.1 christos * pio2_3: third 68 bits of pi/2 47 1.1 christos * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) 48 1.1 christos */ 49 1.1 christos 50 1.1 christos static const double 51 1.1 christos zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ 52 1.1 christos two24 = 1.67772160000000000000e+07; /* 0x41700000, 0x00000000 */ 53 1.1 christos 54 1.1 christos static const long double 55 1.1 christos invpio2 = 6.3661977236758134307553505349005747e-01L, /* 0x145f306dc9c882a53f84eafa3ea6a.0p-113 */ 56 1.1 christos pio2_1 = 1.5707963267948966192292994253909555e+00L, /* 0x1921fb54442d18469800000000000.0p-112 */ 57 1.1 christos pio2_1t = 2.0222662487959507323996846200947577e-21L, /* 0x13198a2e03707344a4093822299f3.0p-181 */ 58 1.1 christos pio2_2 = 2.0222662487959507323994779168837751e-21L, /* 0x13198a2e03707344a400000000000.0p-181 */ 59 1.1 christos pio2_2t = 2.0670321098263988236496903051604844e-43L, /* 0x127044533e63a0105df531d89cd91.0p-254 */ 60 1.1 christos pio2_3 = 2.0670321098263988236499468110329591e-43L, /* 0x127044533e63a0105e00000000000.0p-254 */ 61 1.1 christos pio2_3t = -2.5650587247459238361625433492959285e-65L; /* -0x159c4ec64ddaeb5f78671cbfb2210.0p-327 */ 62 1.1 christos 63 1.1 christos static inline __always_inline int 64 1.1 christos __ieee754_rem_pio2l(long double x, long double *y) 65 1.1 christos { 66 1.1 christos union ieee_ext_u u,u1; 67 1.1 christos long double z,w,t,r,fn; 68 1.1 christos double tx[5],ty[3]; 69 1.1 christos int64_t n; 70 1.1 christos int e0,ex,i,j,nx; 71 1.1 christos int16_t expsign, expsign1; 72 1.1 christos 73 1.1 christos u.extu_ld = x; 74 1.1 christos ex = u.extu_exp; 75 1.1 christos expsign = u.extu_exp | (u.extu_sign << 15); 76 1.1 christos if (ex < BIAS + 45 || (ex == BIAS + 45 && 77 1.1 christos u.extu_frach < 0x921fb54442d1LL)) { 78 1.1 christos /* |x| ~< 2^45*(pi/2), medium size */ 79 1.1 christos /* TODO: use only double precision for fn, as in expl(). */ 80 1.1 christos fn = rnintl(x * invpio2); 81 1.1 christos n = i64rint(fn); 82 1.1 christos r = x-fn*pio2_1; 83 1.1 christos w = fn*pio2_1t; /* 1st round good to 180 bit */ 84 1.1 christos { 85 1.1 christos union ieee_ext_u u2; 86 1.1 christos int ex1; 87 1.1 christos j = ex; 88 1.2 riastrad y[0] = r-w; 89 1.1 christos u2.extu_ld = y[0]; 90 1.1 christos ex1 = u2.extu_exp; 91 1.1 christos i = j-ex1; 92 1.1 christos if(i>51) { /* 2nd iteration needed, good to 248 */ 93 1.1 christos t = r; 94 1.2 riastrad w = fn*pio2_2; 95 1.1 christos r = t-w; 96 1.2 riastrad w = fn*pio2_2t-((t-r)-w); 97 1.1 christos y[0] = r-w; 98 1.1 christos u2.extu_ld = y[0]; 99 1.1 christos ex1 = u2.extu_exp; 100 1.1 christos i = j-ex1; 101 1.1 christos if(i>119) { /* 3rd iteration need, 316 bits acc */ 102 1.2 riastrad t = r; /* will cover all possible cases */ 103 1.2 riastrad w = fn*pio2_3; 104 1.2 riastrad r = t-w; 105 1.2 riastrad w = fn*pio2_3t-((t-r)-w); 106 1.2 riastrad y[0] = r-w; 107 1.1 christos } 108 1.1 christos } 109 1.1 christos } 110 1.1 christos y[1] = (r-y[0])-w; 111 1.1 christos return n; 112 1.1 christos } 113 1.2 riastrad /* 114 1.1 christos * all other (large) arguments 115 1.1 christos */ 116 1.1 christos if(ex==0x7fff) { /* x is inf or NaN */ 117 1.1 christos y[0]=y[1]=x-x; return 0; 118 1.1 christos } 119 1.1 christos /* set z = scalbn(|x|,ilogb(x)-23) */ 120 1.1 christos u1.extu_ld = x; 121 1.1 christos e0 = ex - BIAS - 23; /* e0 = ilogb(|x|)-23; */ 122 1.1 christos expsign1 = ex - e0; 123 1.1 christos u1.extu_exp = expsign1; 124 1.1 christos u1.extu_sign = expsign1 >> 15; 125 1.1 christos z = u1.extu_ld; 126 1.1 christos for(i=0;i<4;i++) { 127 1.1 christos tx[i] = (double)((int32_t)(z)); 128 1.1 christos z = (z-tx[i])*two24; 129 1.1 christos } 130 1.1 christos tx[4] = z; 131 1.1 christos nx = 5; 132 1.1 christos while(tx[nx-1]==zero) nx--; /* skip zero term */ 133 1.1 christos n = __kernel_rem_pio2(tx,ty,e0,nx,3); 134 1.1 christos t = (long double)ty[2] + ty[1]; 135 1.1 christos r = t + ty[0]; 136 1.1 christos w = ty[0] - (r - t); 137 1.1 christos if(expsign<0) {y[0] = -r; y[1] = -w; return -n;} 138 1.1 christos y[0] = r; y[1] = w; return n; 139 1.1 christos } 140