mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 22:50:38 +03:00
Fix-up coefficients and smallest denormal value for ieeeDouble in exp()
This commit is contained in:
parent
aebeac9363
commit
73493bbb49
1 changed files with 44 additions and 25 deletions
69
std/math.d
69
std/math.d
|
@ -1574,36 +1574,55 @@ real exp(real x) @trusted pure nothrow @nogc
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Coefficients for exp(x)
|
alias F = floatTraits!T;
|
||||||
static immutable real[3] P = [
|
static if (F.realFormat == RealFormat.ieeeDouble)
|
||||||
9.9999999999999999991025E-1L,
|
|
||||||
3.0299440770744196129956E-2L,
|
|
||||||
1.2617719307481059087798E-4L,
|
|
||||||
];
|
|
||||||
static immutable real[4] Q = [
|
|
||||||
2.0000000000000000000897E0L,
|
|
||||||
2.2726554820815502876593E-1L,
|
|
||||||
2.5244834034968410419224E-3L,
|
|
||||||
3.0019850513866445504159E-6L,
|
|
||||||
];
|
|
||||||
|
|
||||||
// C1 + C2 = LN2.
|
|
||||||
enum real C1 = 6.9314575195312500000000E-1L;
|
|
||||||
enum real C2 = 1.428606820309417232121458176568075500134E-6L;
|
|
||||||
|
|
||||||
// Overflow and Underflow limits.
|
|
||||||
static if (real.mant_dig == 64) // 80-bit reals
|
|
||||||
{
|
{
|
||||||
enum real OF = 1.1356523406294143949492E4L; // ln((1-2^-64) * 2^16384) ≈ 0x1.62e42fefa39efp+13
|
// Coefficients for exp(x)
|
||||||
enum real UF = -1.1398805384308300613366E4L; // ln(2^-16445) ≈ -0x1.6436716d5406ep+13
|
static immutable real[3] P = [
|
||||||
|
9.99999999999999999910E-1L,
|
||||||
|
3.02994407707441961300E-2L,
|
||||||
|
1.26177193074810590878E-4L,
|
||||||
|
];
|
||||||
|
static immutable real[4] Q = [
|
||||||
|
2.00000000000000000009E0L,
|
||||||
|
2.27265548208155028766E-1L,
|
||||||
|
2.52448340349684104192E-3L,
|
||||||
|
3.00198505138664455042E-6L,
|
||||||
|
];
|
||||||
|
|
||||||
|
// C1 + C2 = LN2.
|
||||||
|
enum real C1 = 6.93145751953125E-1;
|
||||||
|
enum real C2 = 1.42860682030941723212E-6;
|
||||||
|
|
||||||
|
// Overflow and Underflow limits.
|
||||||
|
enum real OF = 7.09782712893383996732E2; // ln((1-2^-53) * 2^1024)
|
||||||
|
enum real UF = -7.451332191019412076235E2; // ln(2^-1075)
|
||||||
}
|
}
|
||||||
else static if (real.mant_dig == 53) // 64-bit reals
|
else static if (F.realFormat == RealFormat.ieeeExtended)
|
||||||
{
|
{
|
||||||
enum real OF = 0x1.62e42fefa39efp+9L; // ln((1-2^-53) * 2^1024) = 709.78271...
|
// Coefficients for exp(x)
|
||||||
enum real UF = -0x1.74385446d71c3p+9L; // ln(2^-1074) = -744.44007...
|
static immutable real[3] P = [
|
||||||
|
9.9999999999999999991025E-1L,
|
||||||
|
3.0299440770744196129956E-2L,
|
||||||
|
1.2617719307481059087798E-4L,
|
||||||
|
];
|
||||||
|
static immutable real[4] Q = [
|
||||||
|
2.0000000000000000000897E0L,
|
||||||
|
2.2726554820815502876593E-1L,
|
||||||
|
2.5244834034968410419224E-3L,
|
||||||
|
3.0019850513866445504159E-6L,
|
||||||
|
];
|
||||||
|
|
||||||
|
// C1 + C2 = LN2.
|
||||||
|
enum real C1 = 6.9314575195312500000000E-1L;
|
||||||
|
enum real C2 = 1.4286068203094172321215E-6L;
|
||||||
|
|
||||||
|
// Overflow and Underflow limits.
|
||||||
|
enum real OF = 1.1356523406294143949492E4L; // ln((1-2^-64) * 2^16384)
|
||||||
|
enum real UF = -1.13994985314888605586758E4L; // ln(2^-16446)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
static assert(0, "No over-/underflow limits for real type!");
|
static assert(0, "Not implemented for this architecture");
|
||||||
|
|
||||||
// Special cases.
|
// Special cases.
|
||||||
// FIXME: set IEEE flags accordingly
|
// FIXME: set IEEE flags accordingly
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue