Home | History | Annotate | Line # | Download | only in ld128
      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