diff --git a/std/math/exp.zig b/std/math/exp.zig index 40eafde39bbd6654836542c31a9ac8a348227556..36c142c87269b5a02b5c71e4eb31778e52529968 100644 --- a/std/math/exp.zig +++ b/std/math/exp.zig @@ -31,6 +31,10 @@ fn exp32(x_: f32) -> f32 { const sign = i32(hx >> 31); hx &= 0x7FFFFFFF; + if (math.isNan(x)) { + return x; + } + // |x| >= -87.33655 or nan if (hx >= 0x42AEAC50) { // nan @@ -108,6 +112,10 @@ fn exp64(x_: f64) -> f64 { const sign = i32(hx >> 31); hx &= 0x7FFFFFFF; + if (math.isNan(x)) { + return x; + } + // |x| >= 708.39 or nan if (hx >= 0x4086232B) { // nan @@ -204,7 +212,6 @@ test "math.exp32.special" { } test "math.exp64.special" { - // TODO: Error on release (like pow) assert(math.isPositiveInf(exp64(math.inf(f64)))); assert(math.isNan(exp64(math.nan(f64)))); } diff --git a/std/math/expm1.zig b/std/math/expm1.zig index 327bf27bcd717efe5012f7bac0bdbd476ee67893..7ffc14b9519066637c14e8f10f37a87577f41c90 100644 --- a/std/math/expm1.zig +++ b/std/math/expm1.zig @@ -258,7 +258,7 @@ fn expm1_64(x_: f64) -> f64 { if (k < 0 or k > 56) { var y = x - e + 1.0; if (k == 1024) { - y = y * 2.0; // TODO: * 0x1.0p1023; + y = y * 2.0 * 0x1.0p1022 * 10; } else { y = y * twopk; } diff --git a/std/math/frexp.zig b/std/math/frexp.zig index 6de126e723f1b0fd0e52e6e561e4fe1d1c7bffad..3c1849c37d401e3e40f2bfc603aca73623d79660 100644 --- a/std/math/frexp.zig +++ b/std/math/frexp.zig @@ -77,8 +77,8 @@ fn frexp64(x: f64) -> frexp64_result { } return result; } else if (e == 0x7FF) { - // frexp(nan) = (nan, 0) result.significand = x; + result.exponent = 0; return result; } @@ -141,7 +141,6 @@ test "math.frexp32.special" { } test "math.frexp64.special" { - // TODO: Error on release mode (like pow) var r: frexp64_result = undefined; r = frexp64(0.0); diff --git a/std/math/pow.zig b/std/math/pow.zig index ed851f8b81f54efbca211739b4953c13ff12817b..042e0c3d1ed2df4a69dfdc2aaf32d1741515fcff 100644 --- a/std/math/pow.zig +++ b/std/math/pow.zig @@ -179,7 +179,6 @@ fn isOddInteger(x: f64) -> bool { test "math.pow" { const epsilon = 0.000001; - // TODO: Error on release assert(math.approxEq(f32, pow(f32, 0.0, 3.3), 0.0, epsilon)); assert(math.approxEq(f32, pow(f32, 0.8923, 3.3), 0.686572, epsilon)); assert(math.approxEq(f32, pow(f32, 0.2, 3.3), 0.004936, epsilon)); diff --git a/std/math/scalbn.zig b/std/math/scalbn.zig index 10ca57d99546c2236b1bffe3c695afc40e9bc292..43fac7c00c29a1e0e15f136f0794b4cecde4998f 100644 --- a/std/math/scalbn.zig +++ b/std/math/scalbn.zig @@ -48,11 +48,10 @@ fn scalbn64(x: f64, n_: i32) -> f64 { var n = n_; if (n > 1023) { - // TODO: Determine how to do the following. - // y *= 0x1.0p1023; + y *= 0x1.0p1022 * 10.0; n -= 1023; if (n > 1023) { - // y *= 0x1.0p1023; + y *= 0x1.0p1022 * 10.0; n -= 1023; if (n > 1023) { n = 1023; diff --git a/std/math/sinh.zig b/std/math/sinh.zig index 019e2f0fbdc593e17866566ff997b2b15e2e8124..e1b001d287508cad049de50c61a301681e6c6b6f 100644 --- a/std/math/sinh.zig +++ b/std/math/sinh.zig @@ -28,6 +28,10 @@ fn sinh32(x: f32) -> f32 { const ux = u & 0x7FFFFFFF; const ax = @bitCast(f32, ux); + if (x == 0.0 or math.isNan(x)) { + return x; + } + var h: f32 = 0.5; if (u >> 31 != 0) { h = -h; @@ -57,6 +61,10 @@ fn sinh64(x: f64) -> f64 { const w = u32(u >> 32); const ax = @bitCast(f64, u & (@maxValue(u64) >> 1)); + if (x == 0.0 or math.isNan(x)) { + return x; + } + var h: f32 = 0.5; if (u >> 63 != 0) { h = -h; @@ -112,7 +120,6 @@ test "math.sinh32.special" { } test "math.sinh64.special" { - // TODO: Error on release mode (like pow) assert(sinh64(0.0) == 0.0); assert(sinh64(-0.0) == -0.0); assert(math.isPositiveInf(sinh64(math.inf(f64)))); diff --git a/std/math/tanh.zig b/std/math/tanh.zig index a76de9ce22af7eacfe9c95e83e66fee46d94ee00..c88dc081561be3e31e5e978c6b340f4f6a133fa5 100644 --- a/std/math/tanh.zig +++ b/std/math/tanh.zig @@ -30,11 +30,15 @@ fn tanh32(x: f32) -> f32 { var t: f32 = undefined; + if (x == 0.0 or math.isNan(x)) { + return x; + } + // |x| < log(3) / 2 ~= 0.5493 or nan if (ux > 0x3F0C9F54) { // |x| > 10 if (ux > 0x41200000) { - t = 1.0 + 0 / x; + t = 1.0; } else { t = math.expm1(2 * x); t = 1 - 2 / (t + 2); @@ -71,10 +75,7 @@ fn tanh64(x: f64) -> f64 { var t: f64 = undefined; // TODO: Shouldn't need these checks. - if (x == 0.0) { - return x; - } - if (math.isNan(x)) { + if (x == 0.0 or math.isNan(x)) { return x; } @@ -82,7 +83,7 @@ fn tanh64(x: f64) -> f64 { if (w > 0x3FE193EA) { // |x| > 20 or nan if (w > 0x40340000) { - t = 1.0; // TODO + 0 / x; + t = 1.0; } else { t = math.expm1(2 * x); t = 1 - 2 / (t + 2); @@ -137,7 +138,6 @@ test "math.tanh64" { } test "math.tanh32.special" { - // TODO: Error on release (like pow) assert(tanh32(0.0) == 0.0); assert(tanh32(-0.0) == -0.0); assert(tanh32(math.inf(f32)) == 1.0);