this repo has no description
at fixPythonPipStalling 528 lines 19 kB view raw
1/* 2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22// GammaDD.c 23// 24// Double-double Function Library 25// Copyright: � 1996 by Apple Computer, Inc., all rights reserved 26// 27// long double gammal( long double x ); 28// long double lgammal( long double x ); 29// 30 31#include "math.h" 32#include "fp_private.h" 33#if (__WANT_LONG_DOUBLE_FORMAT__ - 0L == 128L) 34#include "DD.h" 35 36// Requires the following functions: 37 38void _d3div(double a, double b, double c, double d, double e, double f, 39 double *high, double *mid, double *low); 40void _d3mul(double a, double b, double c, double d, double e, double f, 41 double *high, double *mid, double *low); 42void _d3add(double a, double b, double c, double d, double e, double f, 43 double *high, double *mid, double *low); 44 45long double _LogInnerLD(double, double, double, double *, int); 46long double _ExpInnerLD(double alpha, double beta, double gamma, double *extra, 47 int exptype); 48long double rintl(long double x); 49long double sinl(long double x); 50 51typedef double DD[2]; 52 53// Coefficients for asymptotic formula: 54// real*8 bern(1:2,1:11) 55// FORTRAN: bern(i,j) C: bern[j][i-1] 56// DD *bern = (DD *)(bernData - 4); 57 58static const uint32_t bernData[] __attribute__ ((aligned(8))) = { 59 0x3FB55555, 0x55555555, 0x3C555555, 0x55555555, 60 0xBF66C16C, 0x16C16C17, 0x3BFF49F4, 0x9F49F49F, 61 0x3F4A01A0, 0x1A01A01A, 0x3B8A01A0, 0x1A01A01A, 62 0xBF438138, 0x13813814, 0x3BEFB1FB, 0x1FB1FB20, 63 0x3F4B951E, 0x2B18FF23, 0x3BE5C3A9, 0xCE01B952, 64 0xBF5F6AB0, 0xD9993C7D, 0x3BFF8255, 0x3C999B0E, 65 0x3F7A41A4, 0x1A41A41A, 0x3C106906, 0x90690690, 66 0xBF9E4286, 0xCB0F5398, 0x3C21EFCD, 0xAB896745, 67 0x3FC6FE96, 0x381E0680, 0xBC279E24, 0x05A71F88, 68 0xBFF64767, 0x01181F3A, 0x3C724246, 0x319DA678, 69 0x402ACE44, 0x322CE006, 0xBCC62C2B, 0x1BBCDD32 70}; 71 72// Coefficients of approximating polynomial for LnGamma(2+x) 73// real*8 zeta(1:2,2:53) 74// FORTRAN: zeta(i,j) C: zeta[j][i-1] 75// DD *zeta = (DD *)(zetaData - 8); 76 77static const uint32_t zetaData[] __attribute__ ((aligned(8))) = { 78 0x3FD4A34C, 0xC4A60FA6, 0x3C71873D, 0x8912200C, 79 0xBFB13E00, 0x1A557607, 0x3C5FB68B, 0xE2F8821F, 80 0x3F951322, 0xAC7D8483, 0x3C3AFC89, 0x088CB729, 81 0xBF7E404F, 0xC218F5F2, 0x3C1E4A62, 0x7CF1EB34, 82 0x3F67ADD6, 0xEADB6C30, 0xBBF5B782, 0x8C7FD7F4, 83 0xBF538AC5, 0xC2BF8E08, 0x3BE8A4C1, 0xCFD9CEC8, 84 0x3F40B36A, 0xF86396E9, 0xBBE0698D, 0x6C892967, 85 0xBF2D3FD4, 0xC76D2FC8, 0x3BBC7C55, 0xCFCCBB83, 86 0x3F1A127B, 0x0F17D65A, 0x3BA9D309, 0xAA700268, 87 0xBF078DE5, 0xBD7C81EF, 0x3B7A2054, 0x1CDE47A6, 88 0x3EF580DC, 0xEE66EB02, 0x3B826057, 0x4B258F72, 89 0xBEE3CBC9, 0x63CE2243, 0x3B8EA56E, 0x6C7D5329, 90 0x3ED2597A, 0x39F34AAC, 0xBB7BF911, 0x462A7D81, 91 0xBEC11B2E, 0xB7679541, 0xBB4C76B0, 0xE65AC63A, 92 0x3EB0064C, 0xDEB22F0F, 0x3B4D0156, 0xAFFDBC11, 93 0xBE9E2600, 0xD93CFD2F, 0x3B3130AC, 0x39E5C106, 94 0x3E8C76BB, 0xB3F07A4D, 0x3B2D9A2B, 0x77769B52, 95 0xBE7AF5A6, 0xCBBF8A97, 0xBB195F22, 0x7E96D83E, 96 0x3E699B93, 0xC2070B0F, 0x3B003271, 0x64736428, 97 0xBE5862C7, 0x34DF3EAC, 0xBAFB3280, 0x2BEC0DA0, 98 0x3E47469D, 0xACCFADCD, 0xBAE369D3, 0x88CEBAA9, 99 0xBE36434A, 0x8447AEAD, 0xBA8AF72E, 0xDF876FCD, 100 0x3E2555A8, 0x77FFD2C3, 0xBAC87506, 0x5F26A43B, 101 0xBE147B16, 0x79258D0E, 0xBAB04F36, 0xE0E854E4, 102 0x3E03B15D, 0x2B2FC10C, 0xBA9D79F6, 0xFEEEB28B, 103 0xBDF2F69A, 0x9FABE3E0, 0x3A9A162A, 0xB374C789, 104 0x3DE24932, 0xA337434C, 0x3A806082, 0x9C24508F, 105 0xBDD1A7C2, 0x6EC2523C, 0xBA74F4EB, 0xDB4A04B5, 106 0x3DC11116, 0xE693ED98, 0xBA6C7034, 0xD49E7FC7, 107 0xBDB08424, 0xCBC543D8, 0xBA440EF8, 0x20DBC9EA, 108 0x3DA00002, 0x6E3F644F, 0x3A43546A, 0x6054C889, 109 0xBD8F07C5, 0x14FC9F0A, 0xB9F75B6B, 0xE545AC09, 110 0x3D7E1E20, 0x26AAFCD8, 0xBA162A85, 0x86538620, 111 0xBD6D41D5, 0x6E5EE2E2, 0x39F43894, 0xD27CED5E, 112 0x3D5C71C7, 0xF6F10E37, 0xB9F01074, 0x764D33F2, 113 0xBD4BACF9, 0xA27BC89B, 0x39D4A5A2, 0x15E0508E, 114 0x3D3AF287, 0x18A10D6E, 0x39C40D7F, 0x1B842CC3, 115 0xBD2A41A4, 0x5603E5B6, 0x39C62BE9, 0xCF212D90, 116 0x3D199999, 0xC0716EE9, 0xB9B39E10, 0xF90435CB, 117 0xBD08F9C1, 0xA8DF9D78, 0x3989DA56, 0xD4471922, 118 0x3CF86186, 0x28D28905, 0xB989D7D4, 0xEE5A8893, 119 0xBCE7D05F, 0x4C31C560, 0xB9871BBA, 0x0B7CC339, 120 0x3CD745D1, 0x7B56BA4A, 0x3979D38B, 0xC00D6F02, 121 0xBCC6C16C, 0x1B4D6456, 0xB96AED17, 0x2E5C90F2, 122 0x3CB642C8, 0x5C023D9D, 0xB95DE052, 0x190D755D, 123 0xBCA5C988, 0x2D825E9D, 0x3949723F, 0x1BF240B7, 124 0x3C955555, 0x5698A866, 0x392CF5C8, 0x64970970, 125 0xBC84E5E0, 0xA8022BC9, 0x39128B9D, 0xC88F5BE2, 126 0x3C747AE1, 0x4838081F, 0xB91DF461, 0x306465C0, 127 0xBC641414, 0x146E3E31, 0xB8FE4773, 0xEA1309D6, 128 0x3C53B13B, 0x13EC2F3A, 0x38C41C5B, 0x07A32CA9, 129 0xBC43521C, 0xFB520859, 0xB8E225B1, 0x0AA3CE51 130}; 131 132static const double zero = 0.0; 133static const Double pi = {{0x400921FB, 0x54442D18}}; 134static const Double pib = {{0x3CA1A626, 0x33145C07}}; 135static const Double pic = {{0xB92F1976, 0xB7ED8FBC}}; 136static const Double infinity = {{0x7ff00000, 0x00000000}}; 137static const Double scaleup = {{0x4ff00000, 0x00000000}}; 138static const Double tiny = {{0x0E000000, 0x00000000}}; 139static const Double sclog = {{0x40662E42, 0xFEFA39EF}}; 140static const Double sclog2 = {{0x3CFABC9E, 0x3B39803F}}; 141static const Double sclog3 = {{0x3987B57A, 0x079A1934}}; 142 143static const Double bump = {{0x3FED67F1, 0xC864BEB5}}; // 0.5 ln (2 Pi) 144static const Double bump2 = {{0xBC865B5A, 0x1B7FF5DF}}; 145static const Double bump3 = {{0xB91B7F70, 0xC13DC168}}; 146 147static const Double ec = {{0x3FDB0EE6, 0x072093CE}}; // 1 - Euler's constant 148static const Double ec2 = {{0x3C56CB90, 0x701FBFAB}}; 149static const Double ec3 = {{0x38F34A95, 0xE3133C51}}; 150 151static const Double piln = {{0x3FF250D0, 0x48E7A1BD}}; // log(pi) 152static const Double pilnb = {{0x3C67ABF2, 0xAD8D5088}}; 153static const Double pilnc = {{0xB8E6CCF4, 0x32447B52}}; 154 155static const Double zeta32 = {{0xB914C685, 0x28DDC956}}; // Extra word of precision 156 // for (zeta(2,1),zeta(2,2)) 157 158static long double GammaCommon( double dhead, double dtail, int igamma ) 159{ 160 int signgam, ireflect, increase, i; 161 162 double int1, int2, arg, arg2, arg3, argt, arg2t, anew; 163 double factor, factor1, factor2, factor3, f1, f2, f3; 164 double prod1, prod2, pextra, pextra1, pextra2, sum1, sum2, sextra; 165 double sum21, sum22, sextra2, sum31, sum32, sextra3; 166 double diff1, diff2, dextra, sarg1, sarg2, saextra; 167 double denom1, denom2, sum, suml, sumt, recip1, recip2, recipsq1, recipsq2; 168 double extra, extra2, extra3, extrax, extray, extralg, gmextra; 169 double temp, eexp, diff, z, z2, y, y2, y3, asize, c; 170 171 DblDbl gamdd, tempdd, intdd, xhintdd, sinargdd; 172 173 DD *bern = (DD *)(bernData - 4); 174 DD *zeta = (DD *)(zetaData - 8); 175 176 signgam = 1; 177 178 if (dhead <= 0) { // special for neg arguments 179 tempdd.d[0] = dhead; 180 tempdd.d[1] = dtail; 181 intdd.f = rintl(tempdd.f); // get integer part of argument 182 int1 = intdd.d[0]; 183 int2 = intdd.d[1]; 184 185 if (isinf(dhead) || (dhead - int1 + dtail - int2) == 0) { 186 187 //********************************************************************* 188 // Argument is a non-positive integer. Gamma is not defined. * 189 // Return a NaN. * 190 //********************************************************************* 191 gamdd.d[0] = INFINITY; // per IEC, [was: zero/zero;] 192 gamdd.d[1] = zero; 193 return gamdd.f; 194 } 195 if (dhead > -20.0) { 196 ireflect = 0; // reflection formula not used for 197 // modest sized neg numbers 198 } 199 else { 200 ireflect = 1; // signal use of reflection formula 201 dhead = -dhead; // change sign of argument 202 dtail = -dtail; 203 } 204 } 205 else // else, positive arguments -- 206 ireflect = 0; // signal reflection formula not used 207 208 if (isinf(dhead) || (dhead + dtail) != (dhead + dtail)) { 209 gamdd.d[0] = dhead + dtail; 210 gamdd.d[1] = zero; 211 return gamdd.f; 212 } 213 214 arg = dhead; // working copy of argument 215 arg2 = dtail; 216 arg3 = 0.0; 217 factor1 = 1.0; 218 factor2 = 0.0; 219 factor3 = 0.0; 220 221 if (arg > 18.0) { // use asymptotic formula 222 while (arg < 31.0) { 223 _d3mul( factor1, factor2, factor3, arg, arg2, arg3, 224 &factor1, &factor2, &factor3 ); 225 arg = arg + 1.0; 226 } // argument in range for asympt. formula 227 while (arg < 35.0) { 228 _d3mul( factor1, factor2, factor3, arg, arg2, arg3, 229 &factor1, &factor2, &factor3 ); 230 argt = __FADD( arg, 1.0 ); 231 arg2t = __FADD( (arg - argt + 1.0), arg2 ); 232 arg3 = ((arg - argt + 1.0) - arg2t + arg2) + arg3; 233 arg = argt; 234 arg2 = arg2t; 235 } 236 tempdd.f = _LogInnerLD(arg, arg2, 0.0, &f3, 1); // ln x 237 f3 = f3 + arg3/arg; 238 f1 = tempdd.d[0]; 239 f2 = tempdd.d[1]; 240 241 _d3mul(f1, f2, f3, (arg - 0.5), arg2, arg3, 242 &prod1, &prod2, &c); // (x-.5)ln x 243 _d3add(prod1, prod2, c, -arg, -arg2, -arg3, 244 &sum1, &sum2, &sextra); // (x-.5)ln x-x 245 _d3add(sum1, sum2, sextra, bump.f, bump2.f, bump3.f, 246 &sum21, &sum22, &sextra2); 247 248 //************************************************************** 249 // sum21, sum22, sextra2 represent (x-.5)ln x-x+.5 ln(2 Pi) * 250 //************************************************************** 251 252 _d3div(1.0, 0.0, 0.0, arg, arg2, arg3, &recip1, &recip2, &extra); 253 254 // argument for asymptotic formula 255 _d3mul(recip1, recip2, extra, recip1, recip2, extra, 256 &recipsq1, &recipsq2, &extra2); 257 258 sum = bern[11][0]; 259 suml = bern[11][1]; 260 for (i = 10; i >= 1; --i) { 261 temp = __FMADD( sum, recipsq1, bern[i][0] ); // bern[i][0] + sum*recipsq1; 262 /* suml = bern[i][0] - temp + sum*recipsq1 + 263 (bern[i][1] + sum*recipsq2 + suml*recipsq1); */ 264 suml = __FMADD( sum, recipsq1, bern[i][0] - temp ) + 265 __FMADD( suml, recipsq1, __FMADD( sum, recipsq2, bern[i][1] ) ); 266 sum = temp; 267 } // finish summation of asymptotic series 268 269 _d3mul(sum, suml, 0.0, recip1, recip2, extra, &prod1, &prod2, &extra3); 270 _d3add(sum21, sum22, sextra2, prod1, prod2, extra3, &sum31, &sum32, &sextra3); 271 272 //****************************************************************************** 273 // At this point, log(gamma*factor) is computed as (sum31, sum32, sextra3). * 274 //****************************************************************************** 275 276 if ((igamma == 1) && (ireflect != 1)) { 277 // Gamma entry point (without use of reflection formula)? 278 tempdd.f = _ExpInnerLD(sum31, sum32, sextra3, &eexp, 4); 279 if (factor1 == 1.0) { 280 gamdd.f = tempdd.f; 281 gmextra = eexp; 282 } 283 else { 284 _d3div(tempdd.d[0], tempdd.d[1], eexp, factor1, factor2, factor3, 285 &(gamdd.d[0]), &(gamdd.d[1]), &gmextra); 286 } 287 } 288 else { // Computing log(gamma(x)) 289 factor = factor1; 290 if (factor == 1.0) { 291 gamdd.d[0] = sum31; 292 gamdd.d[1] = sum32; 293 gmextra = sextra3; 294 } 295 else { 296 tempdd.f = _LogInnerLD(factor1, factor2, 0.0, &extrax, 1); 297 // computing log gamma. 298 extray = -(extrax + factor3/factor); 299 _d3add(sum31, sum32, sextra3, -tempdd.d[0], -tempdd.d[1], extray, 300 &(gamdd.d[0]), &(gamdd.d[1]), &gmextra); 301 } 302 } 303 } 304 else { // use formula for interval [0.5,1.5] 305 arg = dhead; 306 arg2 = dtail; // working copy of argument 307 arg3 = 0.0; 308 increase = 0; // signal-> no scaling for result 309 if (arg < 1.5) { // scale up argument by recursion formula 310 increase = -1; // signal-> result to be divided by factor 311 factor1 = arg; 312 factor2 = arg2; 313 factor3 = 0.0; // factor is the old argument 314 while (arg < 1.5) { 315 _d3add(arg, arg2, arg3, 1.0, 0.0, 0.0, &arg, &arg2, &arg3); 316 if (arg < 1.5) { 317 _d3mul(factor1, factor2, factor3, arg, arg2, arg3, 318 &factor1, &factor2, &factor3); 319 } 320 } 321 if (factor1 < 0.0) { 322 signgam = -1; // special case of negative arguments 323 } 324 } 325 else if (arg > 2.5) { 326 increase = +1; // signal-> result must be mult by factor 327 factor1 = 1.0; 328 factor2 = 0.0; 329 factor3 = 0.0; 330 while (arg > 2.5) { // reduce argument by 1 331 arg = arg - 1.0; // there may be room for bits to 332 anew = __FADD( arg, arg2 ); // shift from low order word to 333 arg2 = arg - anew + arg2; // high order word 334 arg = anew; 335 _d3mul(factor1, factor2, factor3, arg, arg2, 0.0, 336 &factor1, &factor2, &factor3); 337 } 338 arg3 = 0.0; 339 } 340 diff = __FSUB( arg, 2.0 ); // series in terms of 341 z = __FADD( (arg - (diff + 2.0)), arg2 ); // (diff,z,x2)=arg-2 342 z2 = (arg - (diff + 2.0)) - z + arg2 + arg3; 343 y = __FADD( diff, z ); 344 y2 = (diff - y + z) + z2; 345 y3 = (diff - y + z) - y2 + z2; 346 sum = zeta[53][0]; 347 suml = zeta[53][1]; 348 for (i = 52; i >= 40; --i) { 349 sum = __FMADD( sum, y, zeta[i][0] ); // zeta[i][0] + sum*y; 350 } 351 sumt = __FMADD( sum, y, zeta[39][0] ); // zeta[39][0] + sum*y; 352 suml = __FMADD( sum, y, zeta[39][0] - sumt) + __FMADD( sum, y2, zeta[39][1] ); // zeta[39][0] - sumt + sum*y + (zeta[39][1] + sum*y2); 353 sum = sumt; 354 for (i = 38; i >= 3; --i) { 355 temp = __FMADD( sum, y, zeta[i][0] ); // zeta[i][0] + sum*y; 356 // suml = (zeta[i][0] - temp + sum*y) + zeta[i][1] + (sum*y2 + suml*y); 357 suml = __FMADD( sum, y, zeta[i][0] - temp ) + zeta[i][1] + __FMADD( sum, y2, suml*y ); 358 sum = temp; 359 } 360 _d3mul(sum, suml, 0.0, y, y2, y3, &prod1, &prod2, &pextra2); 361 _d3add(prod1, prod2, pextra2, zeta[2][0], zeta[2][1], zeta32.f, 362 &sum1, &sum2, &sextra); 363 _d3mul(sum1, sum2, sextra, y, y2, y3, 364 &prod1, &prod2, &pextra1); // multiply sum by z 365 _d3add(prod1, prod2, pextra1, ec.f, ec2.f, ec3.f, 366 &sum1, &sum2, &sextra); // add linear term 367 _d3mul(sum1, sum2, sextra, y, y2, y3, 368 &prod1, &prod2, &pextra); // final mult. by z. 369 370 if (igamma == 1) { // a Gamma entry 371 tempdd.f = _ExpInnerLD(prod1, prod2, pextra, &eexp, 4); 372 if (increase == 1) { 373 _d3mul(tempdd.d[0], tempdd.d[1], eexp, factor1, factor2, factor3, 374 &(gamdd.d[0]), &(gamdd.d[1]), &gmextra); 375 } 376 else if (increase == -1) { 377 _d3div(tempdd.d[0], tempdd.d[1], eexp, factor1, factor2, factor3, 378 &(gamdd.d[0]), &(gamdd.d[1]), &gmextra); 379 } 380 else { 381 gamdd.f = tempdd.f; 382 gmextra = eexp; 383 } 384 } 385 else { // entry was for log gamma 386 if (increase == 0) { 387 gamdd.d[0] = prod1; 388 gamdd.d[1] = prod2; 389 gmextra = pextra; 390 } 391 else { 392 if (signgam < 0) { 393 factor1 = -factor1; 394 factor2 = -factor2; 395 factor3 = -factor3; 396 } 397 factor = factor1; 398 tempdd.f = _LogInnerLD(factor1, factor2, 0.0, &extra, 1); 399 extra = extra + factor3/factor; 400 if (increase == -1) { // change sign of log 401 tempdd.d[0] = -tempdd.d[0]; 402 tempdd.d[1] = -tempdd.d[1]; 403 extra = -extra; 404 } 405 _d3add(prod1, prod2, pextra, tempdd.d[0], tempdd.d[1], extra, 406 &(gamdd.d[0]), &(gamdd.d[1]), &gmextra); 407 } 408 } 409 } 410 411 if (gamdd.d[0] != gamdd.d[0]) { 412 gamdd.d[0] = infinity.f; 413 gamdd.d[1] = zero; 414 gmextra = 0.0; 415 } 416 417 if (ireflect == 1) { // original argument less than 0.0 418 arg = -dhead; // recover original argument 419 arg2 = -dtail; 420 // reduce argument for computation 421 _d3add(arg, arg2, 0.0, -int1, -int2, 0.0, &diff1, &diff2, &dextra); 422 asize = fabs(diff1); 423 424 if (asize < tiny.f) { // For arguments very close 425 diff1 *= scaleup.f; // to an integer, rescale, 426 diff2 *= scaleup.f; // so that sin can be computed 427 dextra *= scaleup.f; // to a full 107+ bits 428 } // of sin (Pi x) 429 430 _d3mul(diff1, diff2, dextra, pi.f, pib.f, pic.f, &sarg1, &sarg2, &saextra); 431 xhintdd.f = 2.0*rintl(0.5*intdd.f); 432 433 tempdd.d[0] = sarg1; 434 tempdd.d[1] = sarg2; 435 sinargdd.f = sinl(tempdd.f); // sin of argument 436 437 if ((xhintdd.d[0] - intdd.d[0] + xhintdd.d[1] - intdd.d[1]) != 0.0) { 438 sinargdd.f = -sinargdd.f; 439 } 440 441 if (sinargdd.d[0] < 0.0) { 442 sinargdd.f = -sinargdd.f; // force sin(pi x) to have plus sign 443 signgam = -signgam; // show gamma(x) has negative sign 444 } 445 446 if (fabs(gamdd.d[0]) == infinity.f){ // result will underflow 447 if(igamma == 1) { 448 gamdd.d[0] = zero; 449 gamdd.d[1] = zero; 450 } 451 else { 452 gamdd.d[0] = -infinity.f; // gamma underflows, so 453 gamdd.d[1] = zero; // lgamma overflows to -INF 454 } 455 return gamdd.f; 456 } 457 _d3mul(dhead, dtail, 0.0, sinargdd.d[0], sinargdd.d[1], 0.0, 458 &prod1, &prod2, &pextra); // x sin(pi x) 459 460 tempdd.f = _LogInnerLD(prod1, prod2, 0.0, &extralg, 1); // log (x sin(pi x)) 461 extralg = extralg + pextra/prod1; 462 _d3add(tempdd.d[0], tempdd.d[1], extralg, gamdd.d[0], gamdd.d[1], gmextra, 463 &denom1, &denom2, &dextra); 464 _d3add(piln.f, pilnb.f, pilnc.f, -denom1, -denom2, -dextra, 465 &(gamdd.d[0]), &(gamdd.d[1]), &gmextra); 466 467 if (asize < tiny.f) { 468 // Compensate for scaling of argument to sin(pi x) 469 _d3add(gamdd.d[0], gamdd.d[1], gmextra, sclog.f, sclog2.f, sclog3.f, 470 &(gamdd.d[0]), &(gamdd.d[1]), &gmextra); 471 } 472 if (igamma == 1) { // we really want gamma itself ? 473 tempdd.f = _ExpInnerLD(gamdd.d[0], gamdd.d[1], gmextra, &eexp, 4); 474 475 if (signgam == 1) { 476 gamdd.f = tempdd.f; 477 } 478 else { 479 gamdd.f = -tempdd.f; 480 } 481 } 482 } 483 return gamdd.f; 484} 485 486long double tgammal( long double x ) 487{ 488 double head, fenv; 489 DblDbl t; 490 491 if (x == 0.0L) 492 return copysignl( INFINITY, x ); 493 494 FEGETENVD(fenv); 495 FESETENVD(0.0); 496 497 t.f = x; 498 499 t.f = GammaCommon(t.d[0], t.d[1], 1); 500 501 head = __FADD( t.d[0], t.d[1] ); 502 t.d[1] = (t.d[0] - head) + t.d[1]; // cannonize tail 503 t.d[0] = head; // cannonize head 504 505 FESETENVD(fenv); 506 return t.f; 507} 508 509long double lgammal( long double x ) 510{ 511 double head, fenv; 512 DblDbl t; 513 514 FEGETENVD(fenv); 515 FESETENVD(0.0); 516 517 t.f = x; 518 519 t.f = GammaCommon(t.d[0], t.d[1], 0); 520 521 head = __FADD( t.d[0], t.d[1] ); 522 t.d[1] = (t.d[0] - head) + t.d[1]; // cannonize tail 523 t.d[0] = head; // cannonize head 524 525 FESETENVD(fenv); 526 return t.f; 527} 528#endif