1 /* e_lgammaf_r.c -- float version of e_lgamma_r.c.
2 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
13 * ====================================================
17 static char rcsid
[] = "$FreeBSD: src/lib/msun/src/e_lgammaf_r.c,v 1.12 2011/10/15 07:00:28 das Exp $";
21 #include "math_private.h"
23 static const volatile float vzero
__attribute__ ((__section__(".rodata,\"a\" " SECTIONCOMMENT
))) = 0.0;
29 pi
= 3.1415927410e+00, /* 0x40490fdb */
31 * Domain y in [0x1p-27, 0.27], range ~[-3.4599e-10, 3.4590e-10]:
32 * |(lgamma(2 - y) + 0.5 * y) / y - a(y)| < 2**-31.4
34 a0
= 7.72156641e-02, /* 0x3d9e233f */
35 a1
= 3.22467119e-01, /* 0x3ea51a69 */
36 a2
= 6.73484802e-02, /* 0x3d89ee00 */
37 a3
= 2.06395667e-02, /* 0x3ca9144f */
38 a4
= 6.98275631e-03, /* 0x3be4cf9b */
39 a5
= 4.11768444e-03, /* 0x3b86eda4 */
41 * Domain x in [tc-0.24, tc+0.28], range ~[-5.6577e-10, 5.5677e-10]:
42 * |(lgamma(x) - tf) - t(x - tc)| < 2**-30.8.
44 tc
= 1.46163213e+00, /* 0x3fbb16c3 */
45 tf
= -1.21486291e-01, /* 0xbdf8cdce */
46 t0
= -2.94064460e-11, /* 0xae0154b7 */
47 t1
= -2.35939837e-08, /* 0xb2caabb8 */
48 t2
= 4.83836412e-01, /* 0x3ef7b968 */
49 t3
= -1.47586212e-01, /* 0xbe1720d7 */
50 t4
= 6.46013096e-02, /* 0x3d844db1 */
51 t5
= -3.28450352e-02, /* 0xbd068884 */
52 t6
= 1.86483748e-02, /* 0x3c98c47a */
53 t7
= -9.89206228e-03, /* 0xbc221251 */
55 * Domain y in [-0.1, 0.232], range ~[-8.4931e-10, 8.7794e-10]:
56 * |(lgamma(1 + y) + 0.5 * y) / y - u(y) / v(y)| < 2**-31.2
58 u0
= -7.72156641e-02, /* 0xbd9e233f */
59 u1
= 7.36789703e-01, /* 0x3f3c9e40 */
60 u2
= 4.95649040e-01, /* 0x3efdc5b6 */
61 v1
= 1.10958421e+00, /* 0x3f8e06db */
62 v2
= 2.10598111e-01, /* 0x3e57a708 */
63 v3
= -1.02995494e-02, /* 0xbc28bf71 */
65 * Domain x in (2, 3], range ~[-5.5189e-11, 5.2317e-11]:
66 * |(lgamma(y+2) - 0.5 * y) / y - s(y)/r(y)| < 2**-35.0
69 s0
= -7.72156641e-02, /* 0xbd9e233f */
70 s1
= 2.69987404e-01, /* 0x3e8a3bca */
71 s2
= 1.42851010e-01, /* 0x3e124789 */
72 s3
= 1.19389519e-02, /* 0x3c439b98 */
73 r1
= 6.79650068e-01, /* 0x3f2dfd8c */
74 r2
= 1.16058730e-01, /* 0x3dedb033 */
75 r3
= 3.75673687e-03, /* 0x3b763396 */
77 * Domain z in [8, 0x1p24], range ~[-1.2640e-09, 1.2640e-09]:
78 * |lgamma(x) - (x - 0.5) * (log(x) - 1) - w(1/x)| < 2**-29.6.
80 w0
= 4.18938547e-01, /* 0x3ed67f1d */
81 w1
= 8.33332464e-02, /* 0x3daaaa9f */
82 w2
= -2.76129087e-03; /* 0xbb34f6c6 */
93 vz
= y
+0x1p
23F
; /* depend on 0 <= y < 0x1p23 */
94 z
= vz
-0x1p
23F
; /* rintf(y) for the above range */
99 GET_FLOAT_WORD(n
,vz
); /* bits for rounded y (units 0.25) */
100 z
= vz
-0x1p
21F
; /* y rounded to a multiple of 0.25 */
102 z
-= 0.25F
; /* adjust to round down */
105 n
&= 7; /* octant of y mod 2 */
106 y
= y
- z
+ n
* 0.25F
; /* y mod 2 */
109 case 0: y
= __kernel_sindf(pi
*y
); break;
111 case 2: y
= __kernel_cosdf(pi
*((float)0.5-y
)); break;
113 case 4: y
= __kernel_sindf(pi
*(one
-y
)); break;
115 case 6: y
= -__kernel_cosdf(pi
*(y
-(float)1.5)); break;
116 default: y
= __kernel_sindf(pi
*(y
-(float)2.0)); break;
123 __ieee754_lgammaf_r(float x
, int *signgamp
)
125 float nadj
,p
,p1
,p2
,q
,r
,t
,w
,y
,z
;
129 GET_FLOAT_WORD(hx
,x
);
131 /* purge +-Inf and NaNs */
134 if(ix
>=0x7f800000) return x
*x
;
136 /* purge +-0 and tiny arguments */
137 *signgamp
= 1-2*((uint32_t)hx
>>31);
138 if(ix
<0x32000000) { /* |x|<2**-27, return -log(|x|) */
141 return -__ieee754_logf(fabsf(x
));
143 /* purge negative integers and start evaluation for other x < 0 */
146 if(ix
>=0x4b000000) /* |x|>=2**23, must be -integer */
149 if(t
==zero
) return one
/vzero
; /* -integer */
150 nadj
= __ieee754_logf(pi
/fabsf(t
*x
));
151 if(t
<zero
) *signgamp
= -1;
156 if (ix
==0x3f800000||ix
==0x40000000) r
= 0;
158 else if(ix
<0x40000000) {
159 if(ix
<=0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */
160 r
= -__ieee754_logf(x
);
161 if(ix
>=0x3f3b4a20) {y
= one
-x
; i
= 0;}
162 else if(ix
>=0x3e6d3308) {y
= x
-(tc
-one
); i
=1;}
166 if(ix
>=0x3fdda618) {y
=2-x
;i
=0;} /* [1.7316,2] */
167 else if(ix
>=0x3F9da620) {y
=x
-tc
;i
=1;} /* [1.23,1.73] */
174 p2
= z
*(a1
+z
*(a3
+z
*a5
));
178 p
= t0
+y
*t1
+y
*y
*(t2
+y
*(t3
+y
*(t4
+y
*(t5
+y
*(t6
+y
*t7
)))));
181 p1
= y
*(u0
+y
*(u1
+y
*u2
));
182 p2
= one
+y
*(v1
+y
*(v2
+y
*v3
));
187 else if(ix
<0x41000000) {
190 p
= y
*(s0
+y
*(s1
+y
*(s2
+y
*s3
)));
191 q
= one
+y
*(r1
+y
*(r2
+y
*r3
));
193 z
= one
; /* lgamma(1+s) = log(s) + lgamma(s) */
195 case 7: z
*= (y
+6); /* FALLTHRU */
196 case 6: z
*= (y
+5); /* FALLTHRU */
197 case 5: z
*= (y
+4); /* FALLTHRU */
198 case 4: z
*= (y
+3); /* FALLTHRU */
199 case 3: z
*= (y
+2); /* FALLTHRU */
200 r
+= __ieee754_logf(z
); break;
202 /* 8.0 <= x < 2**27 */
203 } else if (ix
< 0x4d000000) {
204 t
= __ieee754_logf(x
);
208 r
= (x
-half
)*(t
-one
)+w
;
210 /* 2**27 <= x <= inf */
211 r
= x
*(__ieee754_logf(x
)-one
);
212 if(hx
<0) r
= nadj
- r
;