Print this page
5261 libm should stop using synonyms.h
5298 fabs is 0-sized, confuses dis(1) and others
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Approved by: Gordon Ross <gwr@nexenta.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libm/common/LD/__lgammal.c
+++ new/usr/src/lib/libm/common/LD/__lgammal.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 25 /*
26 26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
27 27 * Use is subject to license terms.
28 28 */
29 29
30 30 /*
31 31 * long double __k_lgammal(long double x, int *signgamlp);
32 32 * K.C. Ng, August, 1989.
33 33 *
34 34 * We choose [1.5,2.5] to be the primary interval. Our algorithms
35 35 * are mainly derived from
36 36 *
37 37 *
38 38 * zeta(2)-1 2 zeta(3)-1 3
39 39 * lgamma(2+s) = s*(1-euler) + --------- * s - --------- * s + ...
40 40 * 2 3
41 41 *
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
42 42 *
43 43 * Note 1. Since gamma(1+s)=s*gamma(s), hence
44 44 * lgamma(1+s) = log(s) + lgamma(s), or
45 45 * lgamma(s) = lgamma(1+s) - log(s).
46 46 * When s is really tiny (like roundoff), lgamma(1+s) ~ s(1-enler)
47 47 * Hence lgamma(s) ~ -log(s) for tiny s
48 48 *
49 49 */
50 50
51 51 #include "libm.h"
52 -#include "libm_synonyms.h"
53 52 #include "longdouble.h"
54 53
55 54 static long double neg(long double, int *);
56 55 static long double poly(long double, const long double *, int);
57 56 static long double polytail(long double);
58 57 static long double primary(long double);
59 58
60 59 static const long double
61 60 c0 = 0.0L,
62 61 ch = 0.5L,
63 62 c1 = 1.0L,
64 63 c2 = 2.0L,
65 64 c3 = 3.0L,
66 65 c4 = 4.0L,
67 66 c5 = 5.0L,
68 67 c6 = 6.0L,
69 68 pi = 3.1415926535897932384626433832795028841971L,
70 69 tiny = 1.0e-40L;
71 70
72 71 long double
73 72 __k_lgammal(long double x, int *signgamlp) {
74 73 long double t, y;
75 74 int i;
76 75
77 76 /* purge off +-inf, NaN and negative arguments */
78 77 if (!finitel(x))
79 78 return (x*x);
80 79 *signgamlp = 1;
81 80 if (signbitl(x))
82 81 return (neg(x, signgamlp));
83 82
84 83 /* for x < 8.0 */
85 84 if (x < 8.0L) {
86 85 y = anintl(x);
87 86 i = (int) y;
88 87 switch (i) {
89 88 case 0:
90 89 if (x < 1.0e-40L)
91 90 return (-logl(x));
92 91 else
93 92 return (primary(x)-log1pl(x))-logl(x);
94 93 case 1:
95 94 return (primary(x-y)-logl(x));
96 95 case 2:
97 96 return (primary(x-y));
98 97 case 3:
99 98 return (primary(x-y)+logl(x-c1));
100 99 case 4:
101 100 return (primary(x-y)+logl((x-c1)*(x-c2)));
102 101 case 5:
103 102 return (primary(x-y)+logl((x-c1)*(x-c2)*(x-c3)));
104 103 case 6:
105 104 return (primary(x-y)+logl((x-c1)*(x-c2)*(x-c3)*(x-c4)));
106 105 case 7:
107 106 return (primary(x-y)+logl((x-c1)*(x-c2)*(x-c3)*(x-c4)*(x-c5)));
108 107 case 8:
109 108 return primary(x-y)+
110 109 logl((x-c1)*(x-c2)*(x-c3)*(x-c4)*(x-c5)*(x-c6));
111 110 }
112 111 }
113 112
114 113 /* 8.0 <= x < 1.0e40 */
115 114 if (x < 1.0e40L) {
116 115 t = logl(x);
117 116 return (x*(t-c1)-(ch*t-polytail(c1/x)));
118 117 }
119 118
120 119 /* 1.0e40 <= x <= inf */
121 120 return (x*(logl(x)-c1));
122 121 }
123 122
124 123 static const long double an1[] = { /* 20 terms */
125 124 -0.0772156649015328606065120900824024309741L,
126 125 3.224670334241132182362075833230130289059e-0001L,
127 126 -6.735230105319809513324605383668929964120e-0002L,
128 127 2.058080842778454787900092432928910226297e-0002L,
129 128 -7.385551028673985266273054086081102125704e-0003L,
130 129 2.890510330741523285758867304409628648727e-0003L,
131 130 -1.192753911703260976581414338096267498555e-0003L,
132 131 5.096695247430424562831956662855697824035e-0004L,
133 132 -2.231547584535777978926798502084300123638e-0004L,
134 133 9.945751278186384670278268034322157947635e-0005L,
135 134 -4.492623673665547726647838474125147631082e-0005L,
136 135 2.050721280617796810096993154281561168706e-0005L,
137 136 -9.439487785617396552092393234044767313568e-0006L,
138 137 4.374872903516051510689234173139793159340e-0006L,
139 138 -2.039156676413643091040459825776029327487e-0006L,
140 139 9.555777181318621470466563543806211523634e-0007L,
141 140 -4.468344919709630637558538313482398989638e-0007L,
142 141 2.216738086090045781773004477831059444178e-0007L,
143 142 -7.472783403418388455860445842543843485916e-0008L,
144 143 8.777317930927149922056782132706238921648e-0008L,
145 144 };
146 145
147 146 static const long double an2[] = { /* 20 terms */
148 147 -.0772156649015328606062692723698127607018L,
149 148 3.224670334241132182635552349060279118047e-0001L,
150 149 -6.735230105319809367555642883133994818325e-0002L,
151 150 2.058080842778459676880822202762143671813e-0002L,
152 151 -7.385551028672828216011343150077846918930e-0003L,
153 152 2.890510330762060607399561536905727853178e-0003L,
154 153 -1.192753911419623262328187532759756368041e-0003L,
155 154 5.096695278636456678258091134532258618614e-0004L,
156 155 -2.231547306817535743052975194022893369135e-0004L,
157 156 9.945771461633313282744264853986643877087e-0005L,
158 157 -4.492503279458972037926876061257489481619e-0005L,
159 158 2.051311416812082875492678651369394595613e-0005L,
160 159 -9.415778282365955203915850761537462941165e-0006L,
161 160 4.452428829045147098722932981088650055919e-0006L,
162 161 -1.835024727987632579886951760650722695781e-0006L,
163 162 1.379783080658545009579060714946381462565e-0006L,
164 163 2.282637532109775156769736768748402175238e-0007L,
165 164 1.002577375515900191362119718128149880168e-0006L,
166 165 5.177028794262638311939991106423220002463e-0007L,
167 166 3.127947245174847104122426445937830555755e-0007L,
168 167 };
169 168
170 169 static const long double an3[] = { /* 20 terms */
171 170 -.0772156649015328227870646417729220690875L,
172 171 3.224670334241156699881788955959915250365e-0001L,
173 172 -6.735230105312273571375431059744975563170e-0002L,
174 173 2.058080842924464587662846071337083809005e-0002L,
175 174 -7.385551008677271654723604653956131791619e-0003L,
176 175 2.890510536479782086197110272583833176602e-0003L,
177 176 -1.192752262076857692740571567808259138697e-0003L,
178 177 5.096800771149805289371135155128380707889e-0004L,
179 178 -2.231000836682831335505058492409860123647e-0004L,
180 179 9.968912171073936803871803966360595275047e-0005L,
181 180 -4.412020779327746243544387946167256187258e-0005L,
182 181 2.281374113541454151067016632998630209049e-0005L,
183 182 -4.028361291428629491824694655287954266830e-0006L,
184 183 1.470694920619518924598956849226530750139e-0005L,
185 184 1.381686137617987197975289545582377713772e-0005L,
186 185 2.012493539265777728944759982054970441601e-0005L,
187 186 1.723917864208965490251560644681933675799e-0005L,
188 187 1.202954035243788300138608765425123713395e-0005L,
189 188 5.079851887558623092776296577030850938146e-0006L,
190 189 1.220657945824153751555138592006604026282e-0006L,
191 190 };
192 191
193 192 static const long double an4[] = { /* 21 terms */
194 193 -.0772156649015732285350261816697540392371L,
195 194 3.224670334221752060691751340365212226097e-0001L,
196 195 -6.735230109744009693977755991488196368279e-0002L,
197 196 2.058080778913037626909954141611580783216e-0002L,
198 197 -7.385557567931505621170483708950557506819e-0003L,
199 198 2.890459838416254326340844289785254883436e-0003L,
200 199 -1.193059036207136762877351596966718455737e-0003L,
201 200 5.081914708100372836613371356529568937869e-0004L,
202 201 -2.289855016133600313131553005982542045338e-0004L,
203 202 8.053454537980585879620331053833498511491e-0005L,
204 203 -9.574620532104845821243493405855672438998e-0005L,
205 204 -9.269085628207107155601445001196317715686e-0005L,
206 205 -2.183276779859490461716196344776208220180e-0004L,
207 206 -3.134834305597571096452454999737269668868e-0004L,
208 207 -3.973878894951937437018305986901392888619e-0004L,
209 208 -3.953352414899222799161275564386488057119e-0004L,
210 209 -3.136740932204038779362660900621212816511e-0004L,
211 210 -1.884502253819634073946130825196078627664e-0004L,
212 211 -8.192655799958926853585332542123631379301e-0005L,
213 212 -2.292183750010571062891605074281744854436e-0005L,
214 213 -3.223980628729716864927724265781406614294e-0006L,
215 214 };
216 215
217 216 static const long double ap1[] = { /* 19 terms */
218 217 -0.0772156649015328606065120900824024296961L,
219 218 3.224670334241132182362075833230047956465e-0001L,
220 219 -6.735230105319809513324605382963943777301e-0002L,
221 220 2.058080842778454787900092126606252375465e-0002L,
222 221 -7.385551028673985266272518231365020063941e-0003L,
223 222 2.890510330741523285681704570797770736423e-0003L,
224 223 -1.192753911703260971285304221165990244515e-0003L,
225 224 5.096695247430420878696018188830886972245e-0004L,
226 225 -2.231547584535654004647639737841526025095e-0004L,
227 226 9.945751278137201960636098805852315982919e-0005L,
228 227 -4.492623672777606053587919463929044226280e-0005L,
229 228 2.050721258703289487603702670753053765201e-0005L,
230 229 -9.439485626565616989352750672499008021041e-0006L,
231 230 4.374838162403994645138200419356844574219e-0006L,
232 231 -2.038979492862555348577006944451002161496e-0006L,
233 232 9.536763152382263548086981191378885102802e-0007L,
234 233 -4.426111214332434049863595231916564014913e-0007L,
235 234 1.911148847512947464234633846270287546882e-0007L,
236 235 -5.788673944861923038157839080272303519671e-0008L,
237 236 };
238 237
239 238 static const long double ap2[] = { /* 19 terms */
240 239 -0.077215664901532860606428624449354836087L,
241 240 3.224670334241132182271948744265855440139e-0001L,
242 241 -6.735230105319809467356126599005051676203e-0002L,
243 242 2.058080842778453315716389815213496002588e-0002L,
244 243 -7.385551028673653323064118422580096222959e-0003L,
245 244 2.890510330735923572088003424849289006039e-0003L,
246 245 -1.192753911629952368606185543945790688144e-0003L,
247 246 5.096695239806718875364547587043220998766e-0004L,
248 247 -2.231547520600616108991867127392089144886e-0004L,
249 248 9.945746913898151120612322833059416008973e-0005L,
250 249 -4.492599307461977003570224943054585729684e-0005L,
251 250 2.050609891889165453592046505651759999090e-0005L,
252 251 -9.435329866734193796540515247917165988579e-0006L,
253 252 4.362267138522223236241016136585565144581e-0006L,
254 253 -2.008556356653246579300491601497510230557e-0006L,
255 254 8.961498103387207161105347118042844354395e-0007L,
256 255 -3.614187228330216282235692806488341157741e-0007L,
257 256 1.136978988247816860500420915014777753153e-0007L,
258 257 -2.000532786387196664019286514899782691776e-0008L,
259 258 };
260 259
261 260 static const long double ap3[] = { /* 19 terms */
262 261 -0.077215664901532859888521470795348856446L,
263 262 3.224670334241131733364048614484228443077e-0001L,
264 263 -6.735230105319676541660495145259038151576e-0002L,
265 264 2.058080842775975461837768839015444273830e-0002L,
266 265 -7.385551028347615729728618066663566606906e-0003L,
267 266 2.890510327517954083379032008643080256676e-0003L,
268 267 -1.192753886919470728001821137439430882603e-0003L,
269 268 5.096693728898932234814903769146577482912e-0004L,
270 269 -2.231540055048827662528594010961874258037e-0004L,
271 270 9.945446210018649311491619999438833843723e-0005L,
272 271 -4.491608206598064519190236245753867697750e-0005L,
273 272 2.047939071322271016498065052853746466669e-0005L,
274 273 -9.376824046522786006677541036631536790762e-0006L,
275 274 4.259329829498149111582277209189150127347e-0006L,
276 275 -1.866064770421594266702176289764212873428e-0006L,
277 276 7.462066721137579592928128104534957135669e-0007L,
278 277 -2.483546217529077735074007138457678727371e-0007L,
279 278 5.915166576378161473299324673649144297574e-0008L,
280 279 -7.334139641706988966966252333759604701905e-0009L,
281 280 };
282 281
283 282 static const long double ap4[] = { /* 19 terms */
284 283 -0.0772156649015326785569313252637238673675L,
285 284 3.224670334241051435008842685722468344822e-0001L,
286 285 -6.735230105302832007479431772160948499254e-0002L,
287 286 2.058080842553481183648529360967441889912e-0002L,
288 287 -7.385551007602909242024706804659879199244e-0003L,
289 288 2.890510182473907253939821312248303471206e-0003L,
290 289 -1.192753098427856770847894497586825614450e-0003L,
291 290 5.096659636418811568063339214203693550804e-0004L,
292 291 -2.231421144004355691166194259675004483639e-0004L,
293 292 9.942073842343832132754332881883387625136e-0005L,
294 293 -4.483809261973204531263252655050701205397e-0005L,
295 294 2.033260142610284888319116654931994447173e-0005L,
296 295 -9.153539544026646699870528191410440585796e-0006L,
297 296 3.988460469925482725894144688699584997971e-0006L,
298 297 -1.609692980087029172567957221850825977621e-0006L,
299 298 5.634916377249975825399706694496688803488e-0007L,
300 299 -1.560065465929518563549083208482591437696e-0007L,
301 300 2.961350193868935325526962209019387821584e-0008L,
302 301 -2.834602215195368130104649234505033159842e-0009L,
303 302 };
304 303
305 304 static long double
306 305 primary(long double s) { /* assume |s|<=0.5 */
307 306 int i;
308 307
309 308 i = (int) (8.0L * (s + 0.5L));
310 309 switch (i) {
311 310 case 0: return ch*s+s*poly(s, an4, 21);
312 311 case 1: return ch*s+s*poly(s, an3, 20);
313 312 case 2: return ch*s+s*poly(s, an2, 20);
314 313 case 3: return ch*s+s*poly(s, an1, 20);
315 314 case 4: return ch*s+s*poly(s, ap1, 19);
316 315 case 5: return ch*s+s*poly(s, ap2, 19);
317 316 case 6: return ch*s+s*poly(s, ap3, 19);
318 317 case 7: return ch*s+s*poly(s, ap4, 19);
319 318 }
320 319 /* NOTREACHED */
321 320 return (0.0L);
322 321 }
323 322
324 323 static long double
325 324 poly(long double s, const long double *p, int n) {
326 325 long double y;
327 326 int i;
328 327 y = p[n-1];
329 328 for (i = n-2; i >= 0; i--) y = p[i]+s*y;
330 329 return (y);
331 330 }
332 331
333 332 static const long double pt[] = {
334 333 9.189385332046727417803297364056176804663e-0001L,
335 334 8.333333333333333333333333333331286969123e-0002L,
336 335 -2.777777777777777777777777553194796036402e-0003L,
337 336 7.936507936507936507927283071433584248176e-0004L,
338 337 -5.952380952380952362351042163192634108297e-0004L,
339 338 8.417508417508395661774286645578379460131e-0004L,
340 339 -1.917526917525263651186066417934685675649e-0003L,
341 340 6.410256409395203164659292973142293199083e-0003L,
342 341 -2.955065327248303301763594514012418438188e-0002L,
343 342 1.796442830099067542945998615411893822886e-0001L,
344 343 -1.392413465829723742489974310411118662919e+0000L,
345 344 1.339984238037267658352656597960492029261e+0001L,
346 345 -1.564707657605373662425785904278645727813e+0002L,
347 346 2.156323807499211356127813962223067079300e+0003L,
348 347 -3.330486427626223184647299834137041307569e+0004L,
349 348 5.235535072011889213611369254140123518699e+0005L,
350 349 -7.258160984602220710491988573430212593080e+0006L,
351 350 7.316526934569686459641438882340322673357e+0007L,
352 351 -3.806450279064900548836571789284896711473e+0008L,
353 352 };
354 353
355 354 static long double
356 355 polytail(long double s) {
357 356 long double t, z;
358 357 int i;
359 358 z = s*s;
360 359 t = pt[18];
361 360 for (i = 17; i >= 1; i--) t = pt[i]+z*t;
362 361 return (pt[0]+s*t);
363 362 }
364 363
365 364 static long double
366 365 neg(long double z, int *signgamlp) {
367 366 long double t, p;
368 367
369 368 /*
370 369 * written by K.C. Ng, Feb 2, 1989.
371 370 *
372 371 * Since
373 372 * -z*G(-z)*G(z) = pi/sin(pi*z),
374 373 * we have
375 374 * G(-z) = -pi/(sin(pi*z)*G(z)*z)
376 375 * = pi/(sin(pi*(-z))*G(z)*z)
377 376 * Algorithm
378 377 * z = |z|
379 378 * t = sinpi(z); ...note that when z>2**112, z is an int
380 379 * and hence t=0.
381 380 *
382 381 * if (t == 0.0) return 1.0/0.0;
383 382 * if (t< 0.0) *signgamlp = -1; else t= -t;
384 383 * if (z<1.0e-40) ...tiny z
385 384 * return -log(z);
386 385 * else
387 386 * return log(pi/(t*z))-lgamma(z);
388 387 *
389 388 */
390 389
391 390 t = sinpil(z); /* t := sin(pi*z) */
392 391 if (t == c0) /* return 1.0/0.0 = +INF */
393 392 return (c1/c0);
394 393
395 394 z = -z;
396 395 if (z <= tiny)
397 396 p = -logl(z);
398 397 else
399 398 p = logl(pi/(fabsl(t)*z)) - __k_lgammal(z, signgamlp);
400 399 if (t < c0) *signgamlp = -1;
401 400 return (p);
402 401 }
↓ open down ↓ |
340 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX