diff options
| author | Marc Tiehuis <marctiehuis@gmail.com> | 2017-06-20 23:01:04 +1200 |
|---|---|---|
| committer | Marc Tiehuis <marctiehuis@gmail.com> | 2017-06-20 23:10:22 +1200 |
| commit | 5bbec42a4edb3f6758a9d67fcf763c660ac3f204 (patch) | |
| tree | 3dc324d083f142935df53c5900edfc04c0f956f8 /std/math/expm1.zig | |
| parent | c9fc8bd802f5ed52c4cc78b93f18fc5dc9b6bb7f (diff) | |
| download | zig-5bbec42a4edb3f6758a9d67fcf763c660ac3f204.tar.gz zig-5bbec42a4edb3f6758a9d67fcf763c660ac3f204.zip | |
Add math special case tests and general fixes
- Should cover special case inputs for most functions
- Fixed a number of runtime panicking behaviour reliant on shift
overflow/division by zero etc.
Diffstat (limited to 'std/math/expm1.zig')
| -rw-r--r-- | std/math/expm1.zig | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/std/math/expm1.zig b/std/math/expm1.zig index c54913299a..327bf27bcd 100644 --- a/std/math/expm1.zig +++ b/std/math/expm1.zig @@ -1,3 +1,9 @@ +// Special Cases: +// +// - expm1(+inf) = +inf +// - expm1(-inf) = -1 +// - expm1(nan) = nan + const math = @import("index.zig"); const assert = @import("../debug.zig").assert; @@ -26,6 +32,11 @@ fn expm1_32(x_: f32) -> f32 { const hx = ux & 0x7FFFFFFF; const sign = hx >> 31; + // TODO: Shouldn't need this check explicitly. + if (math.isNegativeInf(x)) { + return -1.0; + } + // |x| >= 27 * ln2 if (hx >= 0x4195B844) { // nan @@ -113,7 +124,7 @@ fn expm1_32(x_: f32) -> f32 { } } - const twopk = @bitCast(f32, u32(0x7F + k) << 23); + const twopk = @bitCast(f32, u32((0x7F + k) <<% 23)); if (k < 0 or k > 56) { var y = x - e + 1.0; @@ -150,6 +161,10 @@ fn expm1_64(x_: f64) -> f64 { const hx = u32(ux >> 32) & 0x7FFFFFFF; const sign = hx >> 63; + if (math.isNegativeInf(x)) { + return -1.0; + } + // |x| >= 56 * ln2 if (hx >= 0x4043687A) { // exp1md(nan) = nan @@ -162,7 +177,7 @@ fn expm1_64(x_: f64) -> f64 { } if (x > o_threshold) { math.raiseOverflow(); - return math.nan(f64); + return math.inf(f64); } } @@ -238,7 +253,7 @@ fn expm1_64(x_: f64) -> f64 { } } - const twopk = @bitCast(f64, u64(0x3FF + k) << 52); + const twopk = @bitCast(f64, u64(0x3FF + k) <<% 52); if (k < 0 or k > 56) { var y = x - e + 1.0; @@ -283,3 +298,19 @@ test "math.expm1_64" { assert(math.approxEq(f64, expm1_64(0.8923), 1.440737, epsilon)); assert(math.approxEq(f64, expm1_64(1.5), 3.481689, epsilon)); } + +test "math.expm1_32.special" { + const epsilon = 0.000001; + + assert(math.isPositiveInf(expm1_32(math.inf(f32)))); + assert(expm1_32(-math.inf(f32)) == -1.0); + assert(math.isNan(expm1_32(math.nan(f32)))); +} + +test "math.expm1_64.special" { + const epsilon = 0.000001; + + assert(math.isPositiveInf(expm1_64(math.inf(f64)))); + assert(expm1_64(-math.inf(f64)) == -1.0); + assert(math.isNan(expm1_64(math.nan(f64)))); +} |
