diff --git a/lib/std/math/pow.zig b/lib/std/math/pow.zig index efac9f7a3cecff16282637cd844e79d01d00faa0..4eb5fdf1f810fa6f2880cba09fc06c7130aee90c 100644 --- a/lib/std/math/pow.zig +++ b/lib/std/math/pow.zig @@ -13,13 +13,13 @@ const expect = std.testing.expect; /// - pow(x, +-0) = 1 for any x /// - pow(1, y) = 1 for any y /// - pow(x, 1) = x for any x -/// - pow(nan, y) = nan -/// - pow(x, nan) = nan +/// - pow(nan, y) = nan for any y != 0 +/// - pow(x, nan) = nan for any x != 1 /// - pow(+-0, y) = +-inf for y an odd integer < 0 /// - pow(+-0, -inf) = +inf /// - pow(+-0, +inf) = +0 /// - pow(+-0, y) = +inf for finite y < 0 and not an odd integer -/// - pow(+-0, y) = +-0 for y an odd integer > 0 +/// - pow(+-0, y) = +-0 for finite y an odd integer > 0 /// - pow(+-0, y) = +0 for finite y > 0 and not an odd integer /// - pow(-1, +-inf) = 1 /// - pow(x, +inf) = +inf for |x| > 1 @@ -39,20 +39,20 @@ pub fn pow(comptime T: type, x: T, y: T) T { @compileError("pow not implemented for " ++ @typeName(T)); } - // pow(x, +-0) = 1 for all x - // pow(1, y) = 1 for all y + // pow(x, +-0) = 1 for any x + // pow(1, y) = 1 for any y if (y == 0 or x == 1) { return 1; } - // pow(nan, y) = nan for all y - // pow(x, nan) = nan for all x + // pow(nan, y) = nan for any y != 0 + // pow(x, nan) = nan for any x != 1 if (math.isNan(x) or math.isNan(y)) { @branchHint(.unlikely); return math.nan(T); } - // pow(x, 1) = x for all x + // pow(x, 1) = x for any x if (y == 1) { return x; } @@ -77,7 +77,7 @@ pub fn pow(comptime T: type, x: T, y: T) T { } if (math.isInf(y)) { - // pow(-1, inf) = 1 for all x + // pow(-1, inf) = 1 if (x == -1) { return 1.0; } @@ -222,45 +222,86 @@ test pow { } test "special" { - const epsilon = 0.000001; - + // pow(x, +-0) = 1 for any x try expect(pow(f32, 4, 0.0) == 1.0); try expect(pow(f32, 7, -0.0) == 1.0); + try expect(pow(f32, math.nan(f32), -0.0) == 1.0); + // pow(1, y) = 1 for any y + try expect(pow(f32, 1.0, 4) == 1.0); + try expect(pow(f32, 1.0, 7) == 1.0); + try expect(pow(f32, 1.0, -math.inf(f32)) == 1.0); + try expect(pow(f32, 1.0, math.nan(f32)) == 1.0); + // pow(x, 1) = x for any x try expect(pow(f32, 45, 1.0) == 45); try expect(pow(f32, -45, 1.0) == -45); + try expect(math.isPositiveZero(pow(f32, 0.0, 1.0))); + try expect(math.isNegativeZero(pow(f32, -0.0, 1.0))); + try expect(math.isPositiveInf(pow(f32, math.inf(f32), 1.0))); + try expect(math.isNan(pow(f32, math.nan(f32), 1.0))); + // pow(nan, y) = nan for any y != 0 try expect(math.isNan(pow(f32, math.nan(f32), 5.0))); - try expect(math.isPositiveInf(pow(f32, -math.inf(f32), 0.5))); - try expect(math.isPositiveInf(pow(f32, -0.0, -0.5))); - try expect(pow(f32, -0.0, 0.5) == 0); + // pow(x, nan) = nan for any x != 1 try expect(math.isNan(pow(f32, 5.0, math.nan(f32)))); + // pow(+-0, y) = +-inf for y an odd integer < 0 try expect(math.isPositiveInf(pow(f32, 0.0, -1.0))); - //expect(math.isNegativeInf(pow(f32, -0.0, -3.0))); TODO is this required? + try expect(math.isNegativeInf(pow(f32, -0.0, -5.0))); + // pow(+-0, -inf) = +inf try expect(math.isPositiveInf(pow(f32, 0.0, -math.inf(f32)))); try expect(math.isPositiveInf(pow(f32, -0.0, -math.inf(f32)))); - try expect(pow(f32, 0.0, math.inf(f32)) == 0.0); - try expect(pow(f32, -0.0, math.inf(f32)) == 0.0); + // pow(+-0, +inf) = +0 + try expect(math.isPositiveZero(pow(f32, 0.0, math.inf(f32)))); + try expect(math.isPositiveZero(pow(f32, -0.0, math.inf(f32)))); + // pow(+-0, y) = +inf for finite y < 0 and not an odd integer try expect(math.isPositiveInf(pow(f32, 0.0, -2.0))); try expect(math.isPositiveInf(pow(f32, -0.0, -2.0))); - try expect(pow(f32, 0.0, 1.0) == 0.0); - try expect(pow(f32, -0.0, 1.0) == -0.0); - try expect(pow(f32, 0.0, 2.0) == 0.0); - try expect(pow(f32, -0.0, 2.0) == 0.0); - try expect(math.approxEqAbs(f32, pow(f32, -1.0, math.inf(f32)), 1.0, epsilon)); - try expect(math.approxEqAbs(f32, pow(f32, -1.0, -math.inf(f32)), 1.0, epsilon)); + try expect(math.isPositiveInf(pow(f32, 0.0, -5.2))); + try expect(math.isPositiveInf(pow(f32, -0.0, -0.5))); + // pow(+-0, y) = +-0 for finite y an odd integer > 0 + try expect(math.isPositiveZero(pow(f32, 0.0, 3.0))); + try expect(math.isNegativeZero(pow(f32, -0.0, 5.0))); + // pow(+-0, y) = +0 for finite y > 0 and not an odd integer + try expect(math.isPositiveZero(pow(f32, 0.0, 2.0))); + try expect(math.isPositiveZero(pow(f32, -0.0, 2.0))); + try expect(math.isPositiveZero(pow(f32, 0.0, 5.2))); + try expect(math.isPositiveZero(pow(f32, -0.0, 0.5))); + // pow(-1, +-inf) = 1 + try expect(pow(f32, -1.0, math.inf(f32)) == 1.0); + try expect(pow(f32, -1.0, -math.inf(f32)) == 1.0); + // pow(x, +inf) = +inf for |x| > 1 try expect(math.isPositiveInf(pow(f32, 1.2, math.inf(f32)))); try expect(math.isPositiveInf(pow(f32, -1.2, math.inf(f32)))); - try expect(pow(f32, 1.2, -math.inf(f32)) == 0.0); - try expect(pow(f32, -1.2, -math.inf(f32)) == 0.0); - try expect(pow(f32, 0.2, math.inf(f32)) == 0.0); - try expect(pow(f32, -0.2, math.inf(f32)) == 0.0); + // pow(x, -inf) = +0 for |x| > 1 + try expect(math.isPositiveZero(pow(f32, 1.2, -math.inf(f32)))); + try expect(math.isPositiveZero(pow(f32, -1.2, -math.inf(f32)))); + // pow(x, +inf) = +0 for |x| < 1 + try expect(math.isPositiveZero(pow(f32, 0.2, math.inf(f32)))); + try expect(math.isPositiveZero(pow(f32, -0.2, math.inf(f32)))); + // pow(x, -inf) = +inf for |x| < 1 try expect(math.isPositiveInf(pow(f32, 0.2, -math.inf(f32)))); try expect(math.isPositiveInf(pow(f32, -0.2, -math.inf(f32)))); - try expect(math.isPositiveInf(pow(f32, math.inf(f32), 1.0))); - try expect(pow(f32, math.inf(f32), -1.0) == 0.0); - //expect(pow(f32, -math.inf(f32), 5.0) == pow(f32, -0.0, -5.0)); TODO support negative 0? - try expect(pow(f32, -math.inf(f32), -5.2) == pow(f32, -0.0, 5.2)); + // pow(+inf, y) = +inf for y > 0 + try expect(math.isPositiveInf(pow(f32, math.inf(f32), 2.0))); + try expect(math.isPositiveInf(pow(f32, math.inf(f32), 0.2))); + // pow(+inf, y) = +0 for y < 0 + try expect(math.isPositiveZero(pow(f32, math.inf(f32), -2.0))); + try expect(math.isPositiveZero(pow(f32, math.inf(f32), -0.2))); + // pow(-inf, y) = -inf for y an odd integer > 0 + try expect(math.isNegativeInf(pow(f32, -math.inf(f32), 5.0))); + // pow(-inf, +inf) = +inf + try expect(math.isPositiveInf(pow(f32, -math.inf(f32), math.inf(f32)))); + // pow(-inf, -inf) = +0 + try expect(math.isPositiveZero(pow(f32, -math.inf(f32), -math.inf(f32)))); + // pow(-inf, y) = +inf for finite y > 0 and not an odd integer + try expect(math.isPositiveInf(pow(f32, -math.inf(f32), 4.0))); + try expect(math.isPositiveInf(pow(f32, -math.inf(f32), 0.5))); + // pow(-inf, y) = -0 for finite y an odd integer < 0 + try expect(math.isNegativeZero(pow(f32, -math.inf(f32), -3.0))); + // pow(-inf, y) = +0 for finite y < 0 and not an odd integer + try expect(math.isPositiveZero(pow(f32, -math.inf(f32), -2.0))); + try expect(math.isPositiveZero(pow(f32, -math.inf(f32), -5.2))); + // pow(x, y) = nan for finite x < 0 and finite non-integer y try expect(math.isNan(pow(f32, -1.0, 1.2))); - try expect(math.isNan(pow(f32, -12.4, 78.5))); + try expect(math.isNan(pow(f32, -12.4, -78.5))); } test "overflow" {