1 /* @(#)e_lgamma_r.c 1.3 95/01/18 */
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
10 * ====================================================
13 #include <sys/cdefs.h>
14 __FBSDID("$FreeBSD$");
17 * See e_lgamma_r.c for complete comments.
19 * Converted to long double by Steven G. Kargl.
22 #include "../ld/fpmath.h"
24 #include "../ld/math_private.h"
26 static const volatile double vzero
= 0;
33 static const long double
34 pi
= 3.14159265358979323846264338327950288e+00L;
36 * Domain y in [0x1p-119, 0.28], range ~[-1.4065e-36, 1.4065e-36]:
37 * |(lgamma(2 - y) + y / 2) / y - a(y)| < 2**-119.1
39 static const long double
40 a0
= 7.72156649015328606065120900824024296e-02L,
41 a1
= 3.22467033424113218236207583323018498e-01L,
42 a2
= 6.73523010531980951332460538330282217e-02L,
43 a3
= 2.05808084277845478790009252803463129e-02L,
44 a4
= 7.38555102867398526627292839296001626e-03L,
45 a5
= 2.89051033074152328576829509522483468e-03L,
46 a6
= 1.19275391170326097618357349881842913e-03L,
47 a7
= 5.09669524743042462515256340206203019e-04L,
48 a8
= 2.23154758453578096143609255559576017e-04L,
49 a9
= 9.94575127818397632126978731542755129e-05L,
50 a10
= 4.49262367375420471287545895027098145e-05L,
51 a11
= 2.05072127845117995426519671481628849e-05L,
52 a12
= 9.43948816959096748454087141447939513e-06L,
53 a13
= 4.37486780697359330303852050718287419e-06L,
54 a14
= 2.03920783892362558276037363847651809e-06L,
55 a15
= 9.55191070057967287877923073200324649e-07L,
56 a16
= 4.48993286185740853170657139487620560e-07L,
57 a17
= 2.13107543597620911675316728179563522e-07L,
58 a18
= 9.70745379855304499867546549551023473e-08L,
59 a19
= 5.61889970390290257926487734695402075e-08L,
60 a20
= 6.42739653024130071866684358960960951e-09L,
61 a21
= 3.34491062143649291746195612991870119e-08L,
62 a22
= -1.57068547394315223934653011440641472e-08L,
63 a23
= 1.30812825422415841213733487745200632e-08L;
65 * Domain x in [tc-0.24, tc+0.28], range ~[-6.3201e-37, 6.3201e-37]:
66 * |(lgamma(x) - tf) - t(x - tc)| < 2**-120.3.
68 static const long double
69 tc
= 1.46163214496836234126265954232572133e+00L,
70 tf
= -1.21486290535849608095514557177691584e-01L,
71 tt
= 1.57061739945077675484237837992951704e-36L,
72 t0
= -1.99238329499314692728655623767019240e-36L,
73 t1
= -6.08453430711711404116887457663281416e-35L,
74 t2
= 4.83836122723810585213722380854828904e-01L,
75 t3
= -1.47587722994530702030955093950668275e-01L,
76 t4
= 6.46249402389127526561003464202671923e-02L,
77 t5
= -3.27885410884813055008502586863748063e-02L,
78 t6
= 1.79706751152103942928638276067164935e-02L,
79 t7
= -1.03142230366363872751602029672767978e-02L,
80 t8
= 6.10053602051788840313573150785080958e-03L,
81 t9
= -3.68456960831637325470641021892968954e-03L,
82 t10
= 2.25976482322181046611440855340968560e-03L,
83 t11
= -1.40225144590445082933490395950664961e-03L,
84 t12
= 8.78232634717681264035014878172485575e-04L,
85 t13
= -5.54194952796682301220684760591403899e-04L,
86 t14
= 3.51912956837848209220421213975000298e-04L,
87 t15
= -2.24653443695947456542669289367055542e-04L,
88 t16
= 1.44070395420840737695611929680511823e-04L,
89 t17
= -9.27609865550394140067059487518862512e-05L,
90 t18
= 5.99347334438437081412945428365433073e-05L,
91 t19
= -3.88458388854572825603964274134801009e-05L,
92 t20
= 2.52476631610328129217896436186551043e-05L,
93 t21
= -1.64508584981658692556994212457518536e-05L,
94 t22
= 1.07434583475987007495523340296173839e-05L,
95 t23
= -7.03070407519397260929482550448878399e-06L,
96 t24
= 4.60968590693753579648385629003100469e-06L,
97 t25
= -3.02765473778832036018438676945512661e-06L,
98 t26
= 1.99238771545503819972741288511303401e-06L,
99 t27
= -1.31281299822614084861868817951788579e-06L,
100 t28
= 8.60844432267399655055574642052370223e-07L,
101 t29
= -5.64535486432397413273248363550536374e-07L,
102 t30
= 3.99357783676275660934903139592727737e-07L,
103 t31
= -2.95849029193433121795495215869311610e-07L,
104 t32
= 1.37790144435073124976696250804940384e-07L;
106 * Domain y in [-0.1, 0.232], range ~[-1.4046e-37, 1.4181e-37]:
107 * |(lgamma(1 + y) + 0.5 * y) / y - u(y) / v(y)| < 2**-122.8
109 static const long double
110 u0
= -7.72156649015328606065120900824024311e-02L,
111 u1
= 4.24082772271938167430983113242482656e-01L,
112 u2
= 2.96194003481457101058321977413332171e+00L,
113 u3
= 6.49503267711258043997790983071543710e+00L,
114 u4
= 7.40090051288150177152835698948644483e+00L,
115 u5
= 4.94698036296756044610805900340723464e+00L,
116 u6
= 2.00194224610796294762469550684947768e+00L,
117 u7
= 4.82073087750608895996915051568834949e-01L,
118 u8
= 6.46694052280506568192333848437585427e-02L,
119 u9
= 4.17685526755100259316625348933108810e-03L,
120 u10
= 9.06361003550314327144119307810053410e-05L,
121 v1
= 5.15937098592887275994320496999951947e+00L,
122 v2
= 1.14068418766251486777604403304717558e+01L,
123 v3
= 1.41164839437524744055723871839748489e+01L,
124 v4
= 1.07170702656179582805791063277960532e+01L,
125 v5
= 5.14448694179047879915042998453632434e+00L,
126 v6
= 1.55210088094585540637493826431170289e+00L,
127 v7
= 2.82975732849424562719893657416365673e-01L,
128 v8
= 2.86424622754753198010525786005443539e-02L,
129 v9
= 1.35364253570403771005922441442688978e-03L,
130 v10
= 1.91514173702398375346658943749580666e-05L,
131 v11
= -3.25364686890242327944584691466034268e-08L;
133 * Domain x in (2, 3], range ~[-1.3341e-36, 1.3536e-36]:
134 * |(lgamma(y+2) - 0.5 * y) / y - s(y)/r(y)| < 2**-120.1
137 static const long double
138 s0
= -7.72156649015328606065120900824024297e-02L,
139 s1
= 1.23221687850916448903914170805852253e-01L,
140 s2
= 5.43673188699937239808255378293820020e-01L,
141 s3
= 6.31998137119005233383666791176301800e-01L,
142 s4
= 3.75885340179479850993811501596213763e-01L,
143 s5
= 1.31572908743275052623410195011261575e-01L,
144 s6
= 2.82528453299138685507186287149699749e-02L,
145 s7
= 3.70262021550340817867688714880797019e-03L,
146 s8
= 2.83374000312371199625774129290973648e-04L,
147 s9
= 1.15091830239148290758883505582343691e-05L,
148 s10
= 2.04203474281493971326506384646692446e-07L,
149 s11
= 9.79544198078992058548607407635645763e-10L,
150 r1
= 2.58037466655605285937112832039537492e+00L,
151 r2
= 2.86289413392776399262513849911531180e+00L,
152 r3
= 1.78691044735267497452847829579514367e+00L,
153 r4
= 6.89400381446725342846854215600008055e-01L,
154 r5
= 1.70135865462567955867134197595365343e-01L,
155 r6
= 2.68794816183964420375498986152766763e-02L,
156 r7
= 2.64617234244861832870088893332006679e-03L,
157 r8
= 1.52881761239180800640068128681725702e-04L,
158 r9
= 4.63264813762296029824851351257638558e-06L,
159 r10
= 5.89461519146957343083848967333671142e-08L,
160 r11
= 1.79027678176582527798327441636552968e-10L;
162 * Domain z in [8, 0x1p70], range ~[-9.8214e-35, 9.8214e-35]:
163 * |lgamma(x) - (x - 0.5) * (log(x) - 1) - w(1/x)| < 2**-113.0
165 static const long double
166 w0
= 4.18938533204672741780329736405617738e-01L,
167 w1
= 8.33333333333333333333333333332852026e-02L,
168 w2
= -2.77777777777777777777777727810123528e-03L,
169 w3
= 7.93650793650793650791708939493907380e-04L,
170 w4
= -5.95238095238095234390450004444370959e-04L,
171 w5
= 8.41750841750837633887817658848845695e-04L,
172 w6
= -1.91752691752396849943172337347259743e-03L,
173 w7
= 6.41025640880333069429106541459015557e-03L,
174 w8
= -2.95506530801732133437990433080327074e-02L,
175 w9
= 1.79644237328444101596766586979576927e-01L,
176 w10
= -1.39240539108367641920172649259736394e+00L,
177 w11
= 1.33987701479007233325288857758641761e+01L,
178 w12
= -1.56363596431084279780966590116006255e+02L,
179 w13
= 2.14830978044410267201172332952040777e+03L,
180 w14
= -3.28636067474227378352761516589092334e+04L,
181 w15
= 5.06201257747865138432663574251462485e+05L,
182 w16
= -6.79720123352023636706247599728048344e+06L,
183 w17
= 6.57556601705472106989497289465949255e+07L,
184 w18
= -3.26229058141181783534257632389415580e+08L;
187 sin_pil(long double x
)
189 volatile long double vz
;
202 EXTRACT_LDBL128_WORDS(hx
,lx
,n
,vz
);
209 y
= y
- z
+ n
* 0.25;
212 case 0: y
= __kernel_sinl(pi
*y
,zero
,0); break;
214 case 2: y
= __kernel_cosl(pi
*(0.5-y
),zero
); break;
216 case 4: y
= __kernel_sinl(pi
*(one
-y
),zero
,0); break;
218 case 6: y
= -__kernel_cosl(pi
*(y
-1.5),zero
); break;
219 default: y
= __kernel_sinl(pi
*(y
-2.0),zero
,0); break;
225 lgammal_r(long double x
, int *signgamp
)
227 long double nadj
,p
,p1
,p2
,p3
,q
,r
,t
,w
,y
,z
;
232 EXTRACT_LDBL128_WORDS(hx
,lx
,llx
,x
);
234 /* purge +-Inf and NaNs */
237 if(ix
==0x7fff) return x
*x
;
239 /* purge +-0 and tiny arguments */
240 *signgamp
= 1-2*(hx
>>15);
241 if(ix
<0x3fff-116) { /* |x|<2**-(p+3), return -log(|x|) */
244 return -logl(fabsl(x
));
247 /* purge negative integers and start evaluation for other x < 0 */
250 if(ix
>=0x3fff+112) /* |x|>=2**(p-1), must be -integer */
253 if(t
==zero
) return one
/vzero
;
254 nadj
= logl(pi
/fabsl(t
*x
));
255 if(t
<zero
) *signgamp
= -1;
260 if((ix
==0x3fff || ix
==0x4000) && (lx
|llx
)==0) r
= 0;
263 if(x
<=8.9999961853027344e-01) {
265 if(x
>=7.3159980773925781e-01) {y
= 1-x
; i
= 0;}
266 else if(x
>=2.3163998126983643e-01) {y
= x
-(tc
-1); i
=1;}
270 if(x
>=1.7316312789916992e+00) {y
=2-x
;i
=0;}
271 else if(x
>=1.2316322326660156e+00) {y
=x
-tc
;i
=1;}
277 p1
= a0
+z
*(a2
+z
*(a4
+z
*(a6
+z
*(a8
+z
*(a10
+z
*(a12
+z
*(a14
+z
*(a16
+
278 z
*(a18
+z
*(a20
+z
*a22
))))))))));
279 p2
= z
*(a1
+z
*(a3
+z
*(a5
+z
*(a7
+z
*(a9
+z
*(a11
+z
*(a13
+z
*(a15
+
280 z
*(a17
+z
*(a19
+z
*(a21
+z
*a23
)))))))))));
284 p
= t0
+y
*t1
+tt
+y
*y
*(t2
+y
*(t3
+y
*(t4
+y
*(t5
+y
*(t6
+y
*(t7
+y
*(t8
+
285 y
*(t9
+y
*(t10
+y
*(t11
+y
*(t12
+y
*(t13
+y
*(t14
+y
*(t15
+y
*(t16
+
286 y
*(t17
+y
*(t18
+y
*(t19
+y
*(t20
+y
*(t21
+y
*(t22
+y
*(t23
+
287 y
*(t24
+y
*(t25
+y
*(t26
+y
*(t27
+y
*(t28
+y
*(t29
+y
*(t30
+
288 y
*(t31
+y
*t32
))))))))))))))))))))))))))))));
291 p1
= y
*(u0
+y
*(u1
+y
*(u2
+y
*(u3
+y
*(u4
+y
*(u5
+y
*(u6
+y
*(u7
+
292 y
*(u8
+y
*(u9
+y
*u10
))))))))));
293 p2
= one
+y
*(v1
+y
*(v2
+y
*(v3
+y
*(v4
+y
*(v5
+y
*(v6
+y
*(v7
+
294 y
*(v8
+y
*(v9
+y
*(v10
+y
*v11
))))))))));
302 p
= y
*(s0
+y
*(s1
+y
*(s2
+y
*(s3
+y
*(s4
+y
*(s5
+y
*(s6
+y
*(s7
+y
*(s8
+
303 y
*(s9
+y
*(s10
+y
*s11
)))))))))));
304 q
= one
+y
*(r1
+y
*(r2
+y
*(r3
+y
*(r4
+y
*(r5
+y
*(r6
+y
*(r7
+y
*(r8
+
305 y
*(r9
+y
*(r10
+y
*r11
))))))))));
307 z
= 1; /* lgamma(1+s) = log(s) + lgamma(s) */
309 case 7: z
*= (y
+6); /* FALLTHRU */
310 case 6: z
*= (y
+5); /* FALLTHRU */
311 case 5: z
*= (y
+4); /* FALLTHRU */
312 case 4: z
*= (y
+3); /* FALLTHRU */
313 case 3: z
*= (y
+2); /* FALLTHRU */
316 /* 8.0 <= x < 2**(p+3) */
317 } else if (ix
<0x3fff+116) {
321 w
= w0
+z
*(w1
+y
*(w2
+y
*(w3
+y
*(w4
+y
*(w5
+y
*(w6
+y
*(w7
+y
*(w8
+
322 y
*(w9
+y
*(w10
+y
*(w11
+y
*(w12
+y
*(w13
+y
*(w14
+y
*(w15
+y
*(w16
+
323 y
*(w17
+y
*w18
)))))))))))))))));
324 r
= (x
-half
)*(t
-one
)+w
;
325 /* 2**(p+3) <= x <= inf */
328 if(hx
&0x8000) r
= nadj
- r
;