Skip to content

Commit

Permalink
Provide MAXGAMMA, MAXLOG, and MINLOG for 64-bit reals.
Browse files Browse the repository at this point in the history
Also, fix a call to pow() that would overflow for 64-bit reals.
  • Loading branch information
JohanEngelen committed Mar 8, 2015
1 parent 74d2c8a commit 2ac2581
Showing 1 changed file with 25 additions and 4 deletions.
29 changes: 25 additions & 4 deletions std/internal/math/gammafunction.d
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,14 @@ real gammaStirling(real x)
}
else {
w = 1.0L + w * poly( w, SmallStirlingCoeffs);
y = pow( x, x - 0.5L ) / y;
if ( (real.mant_dig == 53) && (x > 143.0L) ) {
// Avoid overflow in pow() for 64-bit reals
real v = pow( x, 0.5L * x - 0.25L );
y = v * (v / y);
}
else {
y = pow( x, x - 0.5L ) / y;
}
}
y = SQRT2PI * y * w;
return y;
Expand Down Expand Up @@ -231,7 +238,12 @@ real igammaTemmeLarge(real a, real x)

public:
/// The maximum value of x for which gamma(x) < real.infinity.
enum real MAXGAMMA = 1755.5483429L;
static if (real.mant_dig == 64) // 80-bit reals
enum real MAXGAMMA = 1755.5483429L;
else static if (real.mant_dig == 53) // 64-bit reals
enum real MAXGAMMA = 171.6243769L;
else
static assert(0, "missing MAXGAMMA for other real types");


/*****************************************************
Expand Down Expand Up @@ -528,8 +540,17 @@ unittest {


private {
enum real MAXLOG = 0x1.62e42fefa39ef358p+13L; // log(real.max)
enum real MINLOG = -0x1.6436716d5406e6d8p+13L; // log(real.min*real.epsilon) = log(smallest denormal)
static if (real.mant_dig == 64) { // 80-bit reals
enum real MAXLOG = 0x1.62e42fefa39ef358p+13L; // log(real.max)
enum real MINLOG = -0x1.6436716d5406e6d8p+13L; // log(real.min_normal*real.epsilon) = log(smallest denormal)
}
else static if (real.mant_dig == 53) { // 64-bit reals
enum real MAXLOG = 0x1.62e430p+9L; // log(real.max)
enum real MINLOG = -0x1.743854p+9L; // log(real.min_normal*real.epsilon) = log(smallest denormal)
}
else
static assert(0, "missing MAXLOG, MINLOG, BETA_BIG, and BETA_BIGINV for other real types");

enum real BETA_BIG = 9.223372036854775808e18L;
enum real BETA_BIGINV = 1.084202172485504434007e-19L;
}
Expand Down

0 comments on commit 2ac2581

Please sign in to comment.