OLD | NEW |
1 /* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_lgammal.c */ | 1 /* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_lgammal.c */ |
2 /* | 2 /* |
3 * ==================================================== | 3 * ==================================================== |
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | 4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
5 * | 5 * |
6 * Developed at SunPro, a Sun Microsystems, Inc. business. | 6 * Developed at SunPro, a Sun Microsystems, Inc. business. |
7 * Permission to use, copy, modify, and distribute this | 7 * Permission to use, copy, modify, and distribute this |
8 * software is freely granted, provided that this notice | 8 * software is freely granted, provided that this notice |
9 * is preserved. | 9 * is preserved. |
10 * ==================================================== | 10 * ==================================================== |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 * lgamma(0) = lgamma(inf) = inf | 83 * lgamma(0) = lgamma(inf) = inf |
84 * lgamma(-integer) = +-inf | 84 * lgamma(-integer) = +-inf |
85 * | 85 * |
86 */ | 86 */ |
87 | 87 |
88 #define _GNU_SOURCE | 88 #define _GNU_SOURCE |
89 #include "libm.h" | 89 #include "libm.h" |
90 #include "libc.h" | 90 #include "libc.h" |
91 | 91 |
92 #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 | 92 #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 |
93 double __lgamma_r(double x, int *sg); | 93 double __lgamma_r(double x, int* sg); |
94 | 94 |
95 long double __lgammal_r(long double x, int *sg) | 95 long double __lgammal_r(long double x, int* sg) { |
96 { | 96 return __lgamma_r(x, sg); |
97 » return __lgamma_r(x, sg); | |
98 } | 97 } |
99 #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 | 98 #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 |
100 static const long double | 99 static const long double |
101 pi = 3.14159265358979323846264L, | 100 pi = 3.14159265358979323846264L, |
102 | 101 |
103 /* lgam(1+x) = 0.5 x + x a(x)/b(x) | 102 /* lgam(1+x) = 0.5 x + x a(x)/b(x) |
104 -0.268402099609375 <= x <= 0 | 103 -0.268402099609375 <= x <= 0 |
105 peak relative error 6.6e-22 */ | 104 peak relative error 6.6e-22 */ |
106 a0 = -6.343246574721079391729402781192128239938E2L, | 105 a0 = -6.343246574721079391729402781192128239938E2L, |
107 a1 = 1.856560238672465796768677717168371401378E3L, | 106 a1 = 1.856560238672465796768677717168371401378E3L, |
108 a2 = 2.404733102163746263689288466865843408429E3L, | 107 a2 = 2.404733102163746263689288466865843408429E3L, |
109 a3 = 8.804188795790383497379532868917517596322E2L, | 108 a3 = 8.804188795790383497379532868917517596322E2L, |
110 a4 = 1.135361354097447729740103745999661157426E2L, | 109 a4 = 1.135361354097447729740103745999661157426E2L, |
111 a5 = 3.766956539107615557608581581190400021285E0L, | 110 a5 = 3.766956539107615557608581581190400021285E0L, |
112 | 111 |
113 b0 = 8.214973713960928795704317259806842490498E3L, | 112 b0 = 8.214973713960928795704317259806842490498E3L, |
114 b1 = 1.026343508841367384879065363925870888012E4L, | 113 b1 = 1.026343508841367384879065363925870888012E4L, |
115 b2 = 4.553337477045763320522762343132210919277E3L, | 114 b2 = 4.553337477045763320522762343132210919277E3L, |
116 b3 = 8.506975785032585797446253359230031874803E2L, | 115 b3 = 8.506975785032585797446253359230031874803E2L, |
117 b4 = 6.042447899703295436820744186992189445813E1L, | 116 b4 = 6.042447899703295436820744186992189445813E1L, |
118 /* b5 = 1.000000000000000000000000000000000000000E0 */ | 117 /* b5 = 1.000000000000000000000000000000000000000E0 */ |
119 | 118 |
120 | 119 tc = 1.4616321449683623412626595423257213284682E0L, |
121 tc = 1.4616321449683623412626595423257213284682E0L, | 120 tf = -1.2148629053584961146050602565082954242826E-1, /* double precision */ |
122 tf = -1.2148629053584961146050602565082954242826E-1, /* double precision */ | 121 /* tt = (tail of tf), i.e. tf + tt has extended precision. */ |
123 /* tt = (tail of tf), i.e. tf + tt has extended precision. */ | 122 tt = 3.3649914684731379602768989080467587736363E-18L, |
124 tt = 3.3649914684731379602768989080467587736363E-18L, | 123 /* lgam ( 1.4616321449683623412626595423257213284682E0 ) = |
125 /* lgam ( 1.4616321449683623412626595423257213284682E0 ) = | 124 -1.2148629053584960809551455717769158215135617312999903886372437313313530E-1 |
126 -1.2148629053584960809551455717769158215135617312999903886372437313313530E-1 */ | 125 */ |
127 | 126 |
128 /* lgam (x + tc) = tf + tt + x g(x)/h(x) | 127 /* lgam (x + tc) = tf + tt + x g(x)/h(x) |
129 -0.230003726999612341262659542325721328468 <= x | 128 -0.230003726999612341262659542325721328468 <= x |
130 <= 0.2699962730003876587373404576742786715318 | 129 <= 0.2699962730003876587373404576742786715318 |
131 peak relative error 2.1e-21 */ | 130 peak relative error 2.1e-21 */ |
132 g0 = 3.645529916721223331888305293534095553827E-18L, | 131 g0 = 3.645529916721223331888305293534095553827E-18L, |
133 g1 = 5.126654642791082497002594216163574795690E3L, | 132 g1 = 5.126654642791082497002594216163574795690E3L, |
134 g2 = 8.828603575854624811911631336122070070327E3L, | 133 g2 = 8.828603575854624811911631336122070070327E3L, |
135 g3 = 5.464186426932117031234820886525701595203E3L, | 134 g3 = 5.464186426932117031234820886525701595203E3L, |
136 g4 = 1.455427403530884193180776558102868592293E3L, | 135 g4 = 1.455427403530884193180776558102868592293E3L, |
137 g5 = 1.541735456969245924860307497029155838446E2L, | 136 g5 = 1.541735456969245924860307497029155838446E2L, |
138 g6 = 4.335498275274822298341872707453445815118E0L, | 137 g6 = 4.335498275274822298341872707453445815118E0L, |
139 | 138 |
140 h0 = 1.059584930106085509696730443974495979641E4L, | 139 h0 = 1.059584930106085509696730443974495979641E4L, |
141 h1 = 2.147921653490043010629481226937850618860E4L, | 140 h1 = 2.147921653490043010629481226937850618860E4L, |
142 h2 = 1.643014770044524804175197151958100656728E4L, | 141 h2 = 1.643014770044524804175197151958100656728E4L, |
143 h3 = 5.869021995186925517228323497501767586078E3L, | 142 h3 = 5.869021995186925517228323497501767586078E3L, |
144 h4 = 9.764244777714344488787381271643502742293E2L, | 143 h4 = 9.764244777714344488787381271643502742293E2L, |
145 h5 = 6.442485441570592541741092969581997002349E1L, | 144 h5 = 6.442485441570592541741092969581997002349E1L, |
146 /* h6 = 1.000000000000000000000000000000000000000E0 */ | 145 /* h6 = 1.000000000000000000000000000000000000000E0 */ |
147 | 146 |
148 | 147 /* lgam (x+1) = -0.5 x + x u(x)/v(x) |
149 /* lgam (x+1) = -0.5 x + x u(x)/v(x) | 148 -0.100006103515625 <= x <= 0.231639862060546875 |
150 -0.100006103515625 <= x <= 0.231639862060546875 | 149 peak relative error 1.3e-21 */ |
151 peak relative error 1.3e-21 */ | 150 u0 = -8.886217500092090678492242071879342025627E1L, |
152 u0 = -8.886217500092090678492242071879342025627E1L, | 151 u1 = 6.840109978129177639438792958320783599310E2L, |
153 u1 = 6.840109978129177639438792958320783599310E2L, | 152 u2 = 2.042626104514127267855588786511809932433E3L, |
154 u2 = 2.042626104514127267855588786511809932433E3L, | 153 u3 = 1.911723903442667422201651063009856064275E3L, |
155 u3 = 1.911723903442667422201651063009856064275E3L, | 154 u4 = 7.447065275665887457628865263491667767695E2L, |
156 u4 = 7.447065275665887457628865263491667767695E2L, | 155 u5 = 1.132256494121790736268471016493103952637E2L, |
157 u5 = 1.132256494121790736268471016493103952637E2L, | 156 u6 = 4.484398885516614191003094714505960972894E0L, |
158 u6 = 4.484398885516614191003094714505960972894E0L, | 157 |
159 | 158 v0 = 1.150830924194461522996462401210374632929E3L, |
160 v0 = 1.150830924194461522996462401210374632929E3L, | 159 v1 = 3.399692260848747447377972081399737098610E3L, |
161 v1 = 3.399692260848747447377972081399737098610E3L, | 160 v2 = 3.786631705644460255229513563657226008015E3L, |
162 v2 = 3.786631705644460255229513563657226008015E3L, | 161 v3 = 1.966450123004478374557778781564114347876E3L, |
163 v3 = 1.966450123004478374557778781564114347876E3L, | 162 v4 = 4.741359068914069299837355438370682773122E2L, |
164 v4 = 4.741359068914069299837355438370682773122E2L, | 163 v5 = 4.508989649747184050907206782117647852364E1L, |
165 v5 = 4.508989649747184050907206782117647852364E1L, | 164 /* v6 = 1.000000000000000000000000000000000000000E0 */ |
166 /* v6 = 1.000000000000000000000000000000000000000E0 */ | 165 |
167 | 166 /* lgam (x+2) = .5 x + x s(x)/r(x) |
168 | 167 0 <= x <= 1 |
169 /* lgam (x+2) = .5 x + x s(x)/r(x) | 168 peak relative error 7.2e-22 */ |
170 0 <= x <= 1 | 169 s0 = 1.454726263410661942989109455292824853344E6L, |
171 peak relative error 7.2e-22 */ | 170 s1 = -3.901428390086348447890408306153378922752E6L, |
172 s0 = 1.454726263410661942989109455292824853344E6L, | 171 s2 = -6.573568698209374121847873064292963089438E6L, |
173 s1 = -3.901428390086348447890408306153378922752E6L, | 172 s3 = -3.319055881485044417245964508099095984643E6L, |
174 s2 = -6.573568698209374121847873064292963089438E6L, | 173 s4 = -7.094891568758439227560184618114707107977E5L, |
175 s3 = -3.319055881485044417245964508099095984643E6L, | 174 s5 = -6.263426646464505837422314539808112478303E4L, |
176 s4 = -7.094891568758439227560184618114707107977E5L, | 175 s6 = -1.684926520999477529949915657519454051529E3L, |
177 s5 = -6.263426646464505837422314539808112478303E4L, | 176 |
178 s6 = -1.684926520999477529949915657519454051529E3L, | 177 r0 = -1.883978160734303518163008696712983134698E7L, |
179 | 178 r1 = -2.815206082812062064902202753264922306830E7L, |
180 r0 = -1.883978160734303518163008696712983134698E7L, | 179 r2 = -1.600245495251915899081846093343626358398E7L, |
181 r1 = -2.815206082812062064902202753264922306830E7L, | 180 r3 = -4.310526301881305003489257052083370058799E6L, |
182 r2 = -1.600245495251915899081846093343626358398E7L, | 181 r4 = -5.563807682263923279438235987186184968542E5L, |
183 r3 = -4.310526301881305003489257052083370058799E6L, | 182 r5 = -3.027734654434169996032905158145259713083E4L, |
184 r4 = -5.563807682263923279438235987186184968542E5L, | 183 r6 = -4.501995652861105629217250715790764371267E2L, |
185 r5 = -3.027734654434169996032905158145259713083E4L, | 184 /* r6 = 1.000000000000000000000000000000000000000E0 */ |
186 r6 = -4.501995652861105629217250715790764371267E2L, | 185 |
187 /* r6 = 1.000000000000000000000000000000000000000E0 */ | 186 /* lgam(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x w(1/x^2) |
188 | 187 x >= 8 |
189 | 188 Peak relative error 1.51e-21 |
190 /* lgam(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x w(1/x^2) | 189 w0 = LS2PI - 0.5 */ |
191 x >= 8 | 190 w0 = 4.189385332046727417803e-1L, w1 = 8.333333333333331447505E-2L, |
192 Peak relative error 1.51e-21 | 191 w2 = -2.777777777750349603440E-3L, w3 = 7.936507795855070755671E-4L, |
193 w0 = LS2PI - 0.5 */ | 192 w4 = -5.952345851765688514613E-4L, w5 = 8.412723297322498080632E-4L, |
194 w0 = 4.189385332046727417803e-1L, | 193 w6 = -1.880801938119376907179E-3L, w7 = 4.885026142432270781165E-3L; |
195 w1 = 8.333333333333331447505E-2L, | |
196 w2 = -2.777777777750349603440E-3L, | |
197 w3 = 7.936507795855070755671E-4L, | |
198 w4 = -5.952345851765688514613E-4L, | |
199 w5 = 8.412723297322498080632E-4L, | |
200 w6 = -1.880801938119376907179E-3L, | |
201 w7 = 4.885026142432270781165E-3L; | |
202 | 194 |
203 /* sin(pi*x) assuming x > 2^-1000, if sin(pi*x)==0 the sign is arbitrary */ | 195 /* sin(pi*x) assuming x > 2^-1000, if sin(pi*x)==0 the sign is arbitrary */ |
204 static long double sin_pi(long double x) | 196 static long double sin_pi(long double x) { |
205 { | 197 int n; |
206 » int n; | 198 |
207 | 199 /* spurious inexact if odd int */ |
208 » /* spurious inexact if odd int */ | 200 x *= 0.5; |
209 » x *= 0.5; | 201 x = 2.0 * (x - floorl(x)); /* x mod 2.0 */ |
210 » x = 2.0*(x - floorl(x)); /* x mod 2.0 */ | 202 |
211 | 203 n = (int)(x * 4.0); |
212 » n = (int)(x*4.0); | 204 n = (n + 1) / 2; |
213 » n = (n+1)/2; | 205 x -= n * 0.5f; |
214 » x -= n*0.5f; | 206 x *= pi; |
215 » x *= pi; | 207 |
216 | 208 switch (n) { |
217 » switch (n) { | 209 default: /* case 4: */ |
218 » default: /* case 4: */ | 210 case 0: |
219 » case 0: return __sinl(x, 0.0, 0); | 211 return __sinl(x, 0.0, 0); |
220 » case 1: return __cosl(x, 0.0); | 212 case 1: |
221 » case 2: return __sinl(-x, 0.0, 0); | 213 return __cosl(x, 0.0); |
222 » case 3: return -__cosl(x, 0.0); | 214 case 2: |
223 » } | 215 return __sinl(-x, 0.0, 0); |
224 } | 216 case 3: |
225 | 217 return -__cosl(x, 0.0); |
226 long double __lgammal_r(long double x, int *sg) { | 218 } |
227 » long double t, y, z, nadj, p, p1, p2, q, r, w; | 219 } |
228 » union ldshape u = {x}; | 220 |
229 » uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48; | 221 long double __lgammal_r(long double x, int* sg) { |
230 » int sign = u.i.se >> 15; | 222 long double t, y, z, nadj, p, p1, p2, q, r, w; |
231 » int i; | 223 union ldshape u = {x}; |
232 | 224 uint32_t ix = (u.i.se & 0x7fffU) << 16 | u.i.m >> 48; |
233 » *sg = 1; | 225 int sign = u.i.se >> 15; |
234 | 226 int i; |
235 » /* purge off +-inf, NaN, +-0, tiny and negative arguments */ | 227 |
236 » if (ix >= 0x7fff0000) | 228 *sg = 1; |
237 » » return x * x; | 229 |
238 » if (ix < 0x3fc08000) { /* |x|<2**-63, return -log(|x|) */ | 230 /* purge off +-inf, NaN, +-0, tiny and negative arguments */ |
239 » » if (sign) { | 231 if (ix >= 0x7fff0000) |
240 » » » *sg = -1; | 232 return x * x; |
241 » » » x = -x; | 233 if (ix < 0x3fc08000) { /* |x|<2**-63, return -log(|x|) */ |
242 » » } | 234 if (sign) { |
243 » » return -logl(x); | 235 *sg = -1; |
244 » } | 236 x = -x; |
245 » if (sign) { | 237 } |
246 » » x = -x; | 238 return -logl(x); |
247 » » t = sin_pi(x); | 239 } |
248 » » if (t == 0.0) | 240 if (sign) { |
249 » » » return 1.0 / (x-x); /* -integer */ | 241 x = -x; |
250 » » if (t > 0.0) | 242 t = sin_pi(x); |
251 » » » *sg = -1; | 243 if (t == 0.0) |
252 » » else | 244 return 1.0 / (x - x); /* -integer */ |
253 » » » t = -t; | 245 if (t > 0.0) |
254 » » nadj = logl(pi / (t * x)); | 246 *sg = -1; |
255 » } | 247 else |
256 | 248 t = -t; |
257 » /* purge off 1 and 2 (so the sign is ok with downward rounding) */ | 249 nadj = logl(pi / (t * x)); |
258 » if ((ix == 0x3fff8000 || ix == 0x40008000) && u.i.m == 0) { | 250 } |
259 » » r = 0; | 251 |
260 » } else if (ix < 0x40008000) { /* x < 2.0 */ | 252 /* purge off 1 and 2 (so the sign is ok with downward rounding) */ |
261 » » if (ix <= 0x3ffee666) { /* 8.99993896484375e-1 */ | 253 if ((ix == 0x3fff8000 || ix == 0x40008000) && u.i.m == 0) { |
262 » » » /* lgamma(x) = lgamma(x+1) - log(x) */ | 254 r = 0; |
263 » » » r = -logl(x); | 255 } else if (ix < 0x40008000) { /* x < 2.0 */ |
264 » » » if (ix >= 0x3ffebb4a) { /* 7.31597900390625e-1 */ | 256 if (ix <= 0x3ffee666) { /* 8.99993896484375e-1 */ |
265 » » » » y = x - 1.0; | 257 /* lgamma(x) = lgamma(x+1) - log(x) */ |
266 » » » » i = 0; | 258 r = -logl(x); |
267 » » » } else if (ix >= 0x3ffced33) { /* 2.31639862060546875e-
1 */ | 259 if (ix >= 0x3ffebb4a) { /* 7.31597900390625e-1 */ |
268 » » » » y = x - (tc - 1.0); | 260 y = x - 1.0; |
269 » » » » i = 1; | 261 i = 0; |
270 » » » } else { /* x < 0.23 */ | 262 } else if (ix >= 0x3ffced33) { /* 2.31639862060546875e-1 */ |
271 » » » » y = x; | 263 y = x - (tc - 1.0); |
272 » » » » i = 2; | 264 i = 1; |
273 » » » } | 265 } else { /* x < 0.23 */ |
274 » » } else { | 266 y = x; |
275 » » » r = 0.0; | 267 i = 2; |
276 » » » if (ix >= 0x3fffdda6) { /* 1.73162841796875 */ | 268 } |
277 » » » » /* [1.7316,2] */ | 269 } else { |
278 » » » » y = x - 2.0; | 270 r = 0.0; |
279 » » » » i = 0; | 271 if (ix >= 0x3fffdda6) { /* 1.73162841796875 */ |
280 » » » } else if (ix >= 0x3fff9da6) { /* 1.23162841796875 */ | 272 /* [1.7316,2] */ |
281 » » » » /* [1.23,1.73] */ | 273 y = x - 2.0; |
282 » » » » y = x - tc; | 274 i = 0; |
283 » » » » i = 1; | 275 } else if (ix >= 0x3fff9da6) { /* 1.23162841796875 */ |
284 » » » } else { | 276 /* [1.23,1.73] */ |
285 » » » » /* [0.9, 1.23] */ | 277 y = x - tc; |
286 » » » » y = x - 1.0; | 278 i = 1; |
287 » » » » i = 2; | 279 } else { |
288 » » » } | 280 /* [0.9, 1.23] */ |
289 » » } | 281 y = x - 1.0; |
290 » » switch (i) { | 282 i = 2; |
291 » » case 0: | 283 } |
292 » » » p1 = a0 + y * (a1 + y * (a2 + y * (a3 + y * (a4 + y * a5
)))); | 284 } |
293 » » » p2 = b0 + y * (b1 + y * (b2 + y * (b3 + y * (b4 + y)))); | 285 switch (i) { |
294 » » » r += 0.5 * y + y * p1/p2; | 286 case 0: |
295 » » » break; | 287 p1 = a0 + y * (a1 + y * (a2 + y * (a3 + y * (a4 + y * a5)))); |
296 » » case 1: | 288 p2 = b0 + y * (b1 + y * (b2 + y * (b3 + y * (b4 + y)))); |
297 » » » p1 = g0 + y * (g1 + y * (g2 + y * (g3 + y * (g4 + y * (g
5 + y * g6))))); | 289 r += 0.5 * y + y * p1 / p2; |
298 » » » p2 = h0 + y * (h1 + y * (h2 + y * (h3 + y * (h4 + y * (h
5 + y))))); | 290 break; |
299 » » » p = tt + y * p1/p2; | 291 case 1: |
300 » » » r += (tf + p); | 292 p1 = g0 + y * (g1 + y * (g2 + y * (g3 + y * (g4 + y * (g5 + y * g6))))); |
301 » » » break; | 293 p2 = h0 + y * (h1 + y * (h2 + y * (h3 + y * (h4 + y * (h5 + y))))); |
302 » » case 2: | 294 p = tt + y * p1 / p2; |
303 » » » p1 = y * (u0 + y * (u1 + y * (u2 + y * (u3 + y * (u4 + y
* (u5 + y * u6)))))); | 295 r += (tf + p); |
304 » » » p2 = v0 + y * (v1 + y * (v2 + y * (v3 + y * (v4 + y * (v
5 + y))))); | 296 break; |
305 » » » r += (-0.5 * y + p1 / p2); | 297 case 2: |
306 » » } | 298 p1 = |
307 » } else if (ix < 0x40028000) { /* 8.0 */ | 299 y * (u0 + |
308 » » /* x < 8.0 */ | 300 y * (u1 + y * (u2 + y * (u3 + y * (u4 + y * (u5 + y * u6)))))); |
309 » » i = (int)x; | 301 p2 = v0 + y * (v1 + y * (v2 + y * (v3 + y * (v4 + y * (v5 + y))))); |
310 » » y = x - (double)i; | 302 r += (-0.5 * y + p1 / p2); |
311 » » p = y * (s0 + y * (s1 + y * (s2 + y * (s3 + y * (s4 + y * (s5 +
y * s6)))))); | 303 } |
312 » » q = r0 + y * (r1 + y * (r2 + y * (r3 + y * (r4 + y * (r5 + y * (
r6 + y)))))); | 304 } else if (ix < 0x40028000) { /* 8.0 */ |
313 » » r = 0.5 * y + p / q; | 305 /* x < 8.0 */ |
314 » » z = 1.0; | 306 i = (int)x; |
315 » » /* lgamma(1+s) = log(s) + lgamma(s) */ | 307 y = x - (double)i; |
316 » » switch (i) { | 308 p = y * |
317 » » case 7: | 309 (s0 + y * (s1 + y * (s2 + y * (s3 + y * (s4 + y * (s5 + y * s6)))))); |
318 » » » z *= (y + 6.0); /* FALLTHRU */ | 310 q = r0 + |
319 » » case 6: | 311 y * (r1 + y * (r2 + y * (r3 + y * (r4 + y * (r5 + y * (r6 + y)))))); |
320 » » » z *= (y + 5.0); /* FALLTHRU */ | 312 r = 0.5 * y + p / q; |
321 » » case 5: | 313 z = 1.0; |
322 » » » z *= (y + 4.0); /* FALLTHRU */ | 314 /* lgamma(1+s) = log(s) + lgamma(s) */ |
323 » » case 4: | 315 switch (i) { |
324 » » » z *= (y + 3.0); /* FALLTHRU */ | 316 case 7: |
325 » » case 3: | 317 z *= (y + 6.0); /* FALLTHRU */ |
326 » » » z *= (y + 2.0); /* FALLTHRU */ | 318 case 6: |
327 » » » r += logl(z); | 319 z *= (y + 5.0); /* FALLTHRU */ |
328 » » » break; | 320 case 5: |
329 » » } | 321 z *= (y + 4.0); /* FALLTHRU */ |
330 » } else if (ix < 0x40418000) { /* 2^66 */ | 322 case 4: |
331 » » /* 8.0 <= x < 2**66 */ | 323 z *= (y + 3.0); /* FALLTHRU */ |
332 » » t = logl(x); | 324 case 3: |
333 » » z = 1.0 / x; | 325 z *= (y + 2.0); /* FALLTHRU */ |
334 » » y = z * z; | 326 r += logl(z); |
335 » » w = w0 + z * (w1 + y * (w2 + y * (w3 + y * (w4 + y * (w5 + y * (
w6 + y * w7)))))); | 327 break; |
336 » » r = (x - 0.5) * (t - 1.0) + w; | 328 } |
337 » } else /* 2**66 <= x <= inf */ | 329 } else if (ix < 0x40418000) { /* 2^66 */ |
338 » » r = x * (logl(x) - 1.0); | 330 /* 8.0 <= x < 2**66 */ |
339 » if (sign) | 331 t = logl(x); |
340 » » r = nadj - r; | 332 z = 1.0 / x; |
341 » return r; | 333 y = z * z; |
| 334 w = w0 + |
| 335 z * (w1 + |
| 336 y * (w2 + y * (w3 + y * (w4 + y * (w5 + y * (w6 + y * w7)))))); |
| 337 r = (x - 0.5) * (t - 1.0) + w; |
| 338 } else /* 2**66 <= x <= inf */ |
| 339 r = x * (logl(x) - 1.0); |
| 340 if (sign) |
| 341 r = nadj - r; |
| 342 return r; |
342 } | 343 } |
343 #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 | 344 #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 |
344 // TODO: broken implementation to make things compile | 345 // TODO: broken implementation to make things compile |
345 double __lgamma_r(double x, int *sg); | 346 double __lgamma_r(double x, int* sg); |
346 | 347 |
347 long double __lgammal_r(long double x, int *sg) | 348 long double __lgammal_r(long double x, int* sg) { |
348 { | 349 return __lgamma_r(x, sg); |
349 » return __lgamma_r(x, sg); | |
350 } | 350 } |
351 #endif | 351 #endif |
352 | 352 |
353 extern int __signgam; | 353 extern int __signgam; |
354 | 354 |
355 long double lgammal(long double x) | 355 long double lgammal(long double x) { |
356 { | 356 return __lgammal_r(x, &__signgam); |
357 » return __lgammal_r(x, &__signgam); | |
358 } | 357 } |
359 | 358 |
360 weak_alias(__lgammal_r, lgammal_r); | 359 weak_alias(__lgammal_r, lgammal_r); |
OLD | NEW |