diff --git a/lib/std/math/acos.zig b/lib/std/math/acos.zig index 4277683d57..f96c3fffb5 100644 --- a/lib/std/math/acos.zig +++ b/lib/std/math/acos.zig @@ -4,6 +4,12 @@ // https://git.musl-libc.org/cgit/musl/tree/src/math/acosf.c // https://git.musl-libc.org/cgit/musl/tree/src/math/acos.c // https://git.musl-libc.org/cgit/musl/tree/src/math/acosl.c +// +// Ported from ARM-software, which is licensed under the MIT license: +// https://github.com/ARM-software/optimized-routines/blob/master/LICENSE +// +// https://github.com/ARM-software/optimized-routines/blob/master/math/aarch64/advsimd/acosf.c +// https://github.com/ARM-software/optimized-routines/blob/master/math/aarch64/advsimd/acos.c const std = @import("../std.zig"); const math = std.math; @@ -17,14 +23,22 @@ const native_endian = builtin.cpu.arch.endian(); /// - acos(x) = nan if x < -1 or x > 1 pub fn acos(x: anytype) @TypeOf(x) { const T = @TypeOf(x); - return switch (T) { - f16 => acosBinary16(x), - f32 => acosBinary32(x), - f64 => acosBinary64(x), - f80 => acosExtended80(x), - f128 => acosBinary128(x), - else => @compileError("acos not implemented for " ++ @typeName(T)), - }; + switch (@typeInfo(T)) { + .float => |info| switch (info.bits) { + 16 => return acosBinary16(x), + 32 => return acosBinary32(x), + 64 => return acosBinary64(x), + 80 => return acosExtended80(x), + 128 => return acosBinary128(x), + else => comptime unreachable, + }, + .vector => |info| switch (info.child) { + f32 => return acosBinary32Vec(info.len, x), + f64 => return acosBinary64Vec(info.len, x), + else => @compileError("unimplemented"), + }, + else => comptime unreachable, + } } fn approxBinary16(z: f32) f32 { @@ -441,3 +455,173 @@ test "acosBinary128" { try testing.expectApproxEqAbs(0x1.513270e671db2d840f20b0186c2cp1, acosBinary128(-0x1.bf887b8c4e33cbef59993056f3dep-1), math.floatEpsAt(f128, 0x1.513270e671db2d840f20b0186c2cp1)); try testing.expectApproxEqAbs(0x1.70851a509f0e8bfbe780aa8f29f9p0, acosBinary128(0x1.0c0f600ab6f9c84c6102942044cep-3), math.floatEpsAt(f128, 0x1.70851a509f0e8bfbe780aa8f29f9p0)); } + +fn acosBinary32Vec(comptime vec_len: comptime_int, x: @Vector(vec_len, f32)) @TypeOf(x) { + const pi: @Vector(vec_len, f32) = @splat(math.pi); + const pi_over_2: @Vector(vec_len, f32) = @splat(math.pi / 2.0); + const zero: @Vector(vec_len, f32) = @splat(0.0); + const half: @Vector(vec_len, f32) = @splat(0.5); + const neg_one: @Vector(vec_len, f32) = @splat(-1.0); + const two: @Vector(vec_len, f32) = @splat(2.0); + const c0: @Vector(vec_len, f32) = @splat(0x1.55555ep-3); + const c1: @Vector(vec_len, f32) = @splat(0x1.33261ap-4); + const c2: @Vector(vec_len, f32) = @splat(0x1.70d7dcp-5); + const c3: @Vector(vec_len, f32) = @splat(0x1.b059dp-6); + const c4: @Vector(vec_len, f32) = @splat(0x1.3af7d8p-5); + + const ax = @abs(x); + const ax_lt_half = ax < half; + const is_neg = x < zero; + const z2 = @select(f32, ax_lt_half, x * x, @mulAdd(@Vector(vec_len, f32), -half, ax, half)); + const z = @select(f32, ax_lt_half, ax, @sqrt(z2)); + const z3 = z2 * z; + const p3_4 = @mulAdd(@Vector(vec_len, f32), z2, c4, c3); + const p2_4 = @mulAdd(@Vector(vec_len, f32), z2, p3_4, c2); + const p1_4 = @mulAdd(@Vector(vec_len, f32), z2, p2_4, c1); + const p0_4 = @mulAdd(@Vector(vec_len, f32), z2, p1_4, c0); + const p = @mulAdd(@Vector(vec_len, f32), z3, p0_4, z); + const mul = @select(f32, ax_lt_half, neg_one, two); + const add = @select(f32, ax_lt_half, pi_over_2, @select(f32, is_neg, pi, zero)); + return @mulAdd(@Vector(vec_len, f32), mul, @select(f32, is_neg, -p, p), add); +} + +fn acosBinary64Vec(comptime vec_len: comptime_int, x: @Vector(vec_len, f64)) @TypeOf(x) { + const pi: @Vector(vec_len, f64) = @splat(math.pi); + const pi_over_2: @Vector(vec_len, f64) = @splat(math.pi / 2.0); + const zero: @Vector(vec_len, f64) = @splat(0.0); + const half: @Vector(vec_len, f64) = @splat(0.5); + const neg_one: @Vector(vec_len, f64) = @splat(-1.0); + const two: @Vector(vec_len, f64) = @splat(2.0); + const c0: @Vector(vec_len, f64) = @splat(0x1.555555555554ep-3); + const c1: @Vector(vec_len, f64) = @splat(0x1.3333333337233p-4); + const c2: @Vector(vec_len, f64) = @splat(0x1.6db6db67f6d9fp-5); + const c3: @Vector(vec_len, f64) = @splat(0x1.f1c71fbd29fbbp-6); + const c4: @Vector(vec_len, f64) = @splat(0x1.6e8b264d467d6p-6); + const c5: @Vector(vec_len, f64) = @splat(0x1.1c5997c357e9dp-6); + const c6: @Vector(vec_len, f64) = @splat(0x1.c86a22cd9389dp-7); + const c7: @Vector(vec_len, f64) = @splat(0x1.856073c22ebbep-7); + const c8: @Vector(vec_len, f64) = @splat(0x1.fd1151acb6bedp-8); + const c9: @Vector(vec_len, f64) = @splat(0x1.087182f799c1dp-6); + const c10: @Vector(vec_len, f64) = @splat(-0x1.6602748120927p-7); + const c11: @Vector(vec_len, f64) = @splat(0x1.cfa0dd1f9478p-6); + + const ax = @abs(x); + const ax_lt_half = ax < half; + const is_neg = x < zero; + const z2 = @select(f64, ax_lt_half, x * x, @mulAdd(@Vector(vec_len, f64), -half, ax, half)); + const z = @select(f64, ax_lt_half, ax, @sqrt(z2)); + const z3 = z2 * z; + const z4 = z2 * z2; + const z8 = z4 * z4; + const p0_1 = @mulAdd(@Vector(vec_len, f64), z2, c1, c0); + const p2_3 = @mulAdd(@Vector(vec_len, f64), z2, c3, c2); + const p0_3 = @mulAdd(@Vector(vec_len, f64), z4, p2_3, p0_1); + const p4_5 = @mulAdd(@Vector(vec_len, f64), z2, c5, c4); + const p6_7 = @mulAdd(@Vector(vec_len, f64), z2, c7, c6); + const p4_7 = @mulAdd(@Vector(vec_len, f64), z4, p6_7, p4_5); + const p8_9 = @mulAdd(@Vector(vec_len, f64), z2, c9, c8); + const p10_11 = @mulAdd(@Vector(vec_len, f64), z2, c11, c10); + const p8_11 = @mulAdd(@Vector(vec_len, f64), z4, p10_11, p8_9); + const p4_11 = @mulAdd(@Vector(vec_len, f64), z8, p8_11, p4_7); + const p0_11 = @mulAdd(@Vector(vec_len, f64), z8, p4_11, p0_3); + const p = @mulAdd(@Vector(vec_len, f64), z3, p0_11, z); + const mul = @select(f64, ax_lt_half, neg_one, two); + const add = @select(f64, ax_lt_half, pi_over_2, @select(f64, is_neg, pi, zero)); + return @mulAdd(@Vector(vec_len, f64), mul, @select(f64, is_neg, -p, p), add); +} + +test "acosBinary32Vec.special" { + const input: @Vector(8, f32) = .{ + 0x0p+0, + -0x1p+0, + 0x1p+0, + 0x1.000002p+0, + -0x1.000002p+0, + math.inf(f32), + -math.inf(f32), + math.nan(f32), + }; + const output = acosBinary32Vec(8, input); + try testing.expectApproxEqAbs(0x1.921fb6p+0, output[0], math.floatEpsAt(f32, 0x1.921fb6p+0)); + try testing.expectApproxEqAbs(0x1.921fb6p+1, output[1], math.floatEpsAt(f32, 0x1.921fb6p+1)); + try testing.expectEqual(0x0p+0, output[2]); + try testing.expect(math.isNan(output[3])); + try testing.expect(math.isNan(output[4])); + try testing.expect(math.isNan(output[5])); + try testing.expect(math.isNan(output[6])); + try testing.expect(math.isNan(output[7])); +} + +test "acosBinary32Vec" { + const input: @Vector(10, f32) = .{ + -0x1.13284cp-2, + 0x1.6ca8ep-1, + 0x1.c2ca6p-1, + -0x1.55f12p-1, + -0x1.15679ep-2, + -0x1.41e132p-5, + 0x1.281b0ep-1, + 0x1.b5ce34p-1, + -0x1.583482p-3, + -0x1.ea8224p-1, + }; + const output = acosBinary32Vec(10, input); + try testing.expectApproxEqAbs(0x1.d7c4e6p+0, output[0], math.floatEpsAt(f32, 0x1.d7c4e6p+0)); + try testing.expectApproxEqAbs(0x1.8e6756p-1, output[1], math.floatEpsAt(f32, 0x1.8e6756p-1)); + try testing.expectApproxEqAbs(0x1.f9d74cp-2, output[2], math.floatEpsAt(f32, 0x1.f9d74cp-2)); + try testing.expectApproxEqAbs(0x1.26abdcp+1, output[3], math.floatEpsAt(f32, 0x1.26abdcp+1)); + try testing.expectApproxEqAbs(0x1.d85a44p+0, output[4], math.floatEpsAt(f32, 0x1.d85a44p+0)); + try testing.expectApproxEqAbs(0x1.9c2f68p+0, output[5], math.floatEpsAt(f32, 0x1.9c2f68p+0)); + try testing.expectApproxEqAbs(0x1.e881bp-1, output[6], math.floatEpsAt(f32, 0x1.e881bp-1)); + try testing.expectApproxEqAbs(0x1.1713f6p-1, output[7], math.floatEpsAt(f32, 0x1.1713f6p-1)); + try testing.expectApproxEqAbs(0x1.bd5accp+0, output[8], math.floatEpsAt(f32, 0x1.bd5accp+0)); + try testing.expectApproxEqAbs(0x1.6ce7d8p+1, output[9], math.floatEpsAt(f32, 0x1.6ce7d8p+1)); +} + +test "acosBinary64Vec.special" { + const input: @Vector(8, f64) = .{ + 0x0p+0, + -0x1p+0, + 0x1p+0, + 0x1.0000000000001p+0, + -0x1.0000000000001p+0, + math.inf(f64), + -math.inf(f64), + math.nan(f64), + }; + const output = acosBinary64Vec(8, input); + try testing.expectApproxEqAbs(0x1.921fb54442d18p+0, output[0], math.floatEpsAt(f64, 0x1.921fb54442d18p+0)); + try testing.expectApproxEqAbs(0x1.921fb54442d18p+1, output[1], math.floatEpsAt(f64, 0x1.921fb54442d18p+1)); + try testing.expectEqual(0x0p+0, output[2]); + try testing.expect(math.isNan(output[3])); + try testing.expect(math.isNan(output[4])); + try testing.expect(math.isNan(output[5])); + try testing.expect(math.isNan(output[6])); + try testing.expect(math.isNan(output[7])); +} + +test "acosBinary64Vec" { + const input: @Vector(10, f64) = .{ + -0x1.13284b2b5006dp-2, + 0x1.6ca8dfb825911p-1, + 0x1.c2ca609de7505p-1, + -0x1.55f11fba96889p-1, + -0x1.15679e27084ddp-2, + -0x1.41e131b093c41p-5, + 0x1.281b0d18455f5p-1, + 0x1.b5ce34a51b239p-1, + -0x1.583481079de4dp-3, + -0x1.ea8223103b871p-1, + }; + const output = acosBinary64Vec(10, input); + try testing.expectApproxEqAbs(0x1.d7c4e61020905p+0, output[0], math.floatEpsAt(f64, 0x1.d7c4e61020905p+0)); + try testing.expectApproxEqAbs(0x1.8e6756e27c366p-1, output[1], math.floatEpsAt(f64, 0x1.8e6756e27c366p-1)); + try testing.expectApproxEqAbs(0x1.f9d748eaf956p-2, output[2], math.floatEpsAt(f64, 0x1.f9d748eaf956p-2)); + try testing.expectApproxEqAbs(0x1.26abdc68d07aap+1, output[3], math.floatEpsAt(f64, 0x1.26abdc68d07aap+1)); + try testing.expectApproxEqAbs(0x1.d85a44ea44fe4p+0, output[4], math.floatEpsAt(f64, 0x1.d85a44ea44fe4p+0)); + try testing.expectApproxEqAbs(0x1.9c2f688eee8abp+0, output[5], math.floatEpsAt(f64, 0x1.9c2f688eee8abp+0)); + try testing.expectApproxEqAbs(0x1.e881b1d4eb2a1p-1, output[6], math.floatEpsAt(f64, 0x1.e881b1d4eb2a1p-1)); + try testing.expectApproxEqAbs(0x1.1713f567a87efp-1, output[7], math.floatEpsAt(f64, 0x1.1713f567a87efp-1)); + try testing.expectApproxEqAbs(0x1.bd5acbe8fcc59p+0, output[8], math.floatEpsAt(f64, 0x1.bd5acbe8fcc59p+0)); + try testing.expectApproxEqAbs(0x1.6ce7d66f628e5p+1, output[9], math.floatEpsAt(f64, 0x1.6ce7d66f628e5p+1)); +} diff --git a/lib/std/math/asin.zig b/lib/std/math/asin.zig index af8f3521b3..7c5eb68d01 100644 --- a/lib/std/math/asin.zig +++ b/lib/std/math/asin.zig @@ -4,6 +4,12 @@ // https://git.musl-libc.org/cgit/musl/tree/src/math/asinf.c // https://git.musl-libc.org/cgit/musl/tree/src/math/asin.c // https://git.musl-libc.org/cgit/musl/tree/src/math/asinl.c +// +// Ported from ARM-software, which is licensed under the MIT license: +// https://github.com/ARM-software/optimized-routines/blob/master/LICENSE +// +// https://github.com/ARM-software/optimized-routines/blob/master/math/aarch64/advsimd/asinf.c +// https://github.com/ARM-software/optimized-routines/blob/master/math/aarch64/advsimd/asin.c const std = @import("../std.zig"); const math = std.math; @@ -19,14 +25,22 @@ const native_endian = builtin.cpu.arch.endian(); /// - asin(x) = nan if x < -1 or x > 1 pub fn asin(x: anytype) @TypeOf(x) { const T = @TypeOf(x); - return switch (T) { - f16 => asinBinary16(x), - f32 => asinBinary32(x), - f64 => asinBinary64(x), - f80 => asinExtended80(x), - f128 => asinBinary128(x), - else => @compileError("asin not implemented for " ++ @typeName(T)), - }; + switch (@typeInfo(T)) { + .float => |info| switch (info.bits) { + 16 => return asinBinary16(x), + 32 => return asinBinary32(x), + 64 => return asinBinary64(x), + 80 => return asinExtended80(x), + 128 => return asinBinary128(x), + else => comptime unreachable, + }, + .vector => |info| switch (info.child) { + f32 => return asinBinary32Vec(info.len, x), + f64 => return asinBinary64Vec(info.len, x), + else => @compileError("unimplemented"), + }, + else => comptime unreachable, + } } fn approxBinary16(z: f32) f32 { @@ -435,3 +449,169 @@ test "asinBinary128" { try testing.expectApproxEqAbs(-0x1.97f1092fd94ac0fdfddae2e1222bp-1, asinBinary128(-0x1.6e210214e40edf6c8479998189d1p-1), math.floatEpsAt(f128, -0x1.97f1092fd94ac0fdfddae2e1222bp-1)); try testing.expectApproxEqAbs(-0x1.97b62bc5ae6512093828828325e1p-3, asinBinary128(-0x1.95061bf93ed6986a45d20f0e1064p-3), math.floatEpsAt(f128, -0x1.97b62bc5ae6512093828828325e1p-3)); } + +fn asinBinary32Vec(comptime vec_len: comptime_int, x: @Vector(vec_len, f32)) @TypeOf(x) { + const pi_over_2: @Vector(vec_len, f32) = @splat(math.pi / 2.0); + const zero: @Vector(vec_len, f32) = @splat(0.0); + const half: @Vector(vec_len, f32) = @splat(0.5); + const neg_two: @Vector(vec_len, f32) = @splat(-2.0); + const c0: @Vector(vec_len, f32) = @splat(0x1.55555ep-3); + const c1: @Vector(vec_len, f32) = @splat(0x1.33261ap-4); + const c2: @Vector(vec_len, f32) = @splat(0x1.70d7dcp-5); + const c3: @Vector(vec_len, f32) = @splat(0x1.b059dp-6); + const c4: @Vector(vec_len, f32) = @splat(0x1.3af7d8p-5); + + const ax = @abs(x); + const ax_lt_half = ax < half; + const z2 = @select(f32, ax_lt_half, x * x, @mulAdd(@Vector(vec_len, f32), -half, ax, half)); + const z = @select(f32, ax_lt_half, ax, @sqrt(z2)); + const z3 = z2 * z; + const p3_4 = @mulAdd(@Vector(vec_len, f32), z2, c4, c3); + const p2_4 = @mulAdd(@Vector(vec_len, f32), z2, p3_4, c2); + const p1_4 = @mulAdd(@Vector(vec_len, f32), z2, p2_4, c1); + const p0_4 = @mulAdd(@Vector(vec_len, f32), z2, p1_4, c0); + const p = @mulAdd(@Vector(vec_len, f32), z3, p0_4, z); + const y = @select(f32, ax_lt_half, p, @mulAdd(@Vector(vec_len, f32), p, neg_two, pi_over_2)); + return @select(f32, x < zero, -y, y); +} + +fn asinBinary64Vec(comptime vec_len: comptime_int, x: @Vector(vec_len, f64)) @TypeOf(x) { + const pi_over_2: @Vector(vec_len, f64) = @splat(math.pi / 2.0); + const zero: @Vector(vec_len, f64) = @splat(0.0); + const half: @Vector(vec_len, f64) = @splat(0.5); + const neg_two: @Vector(vec_len, f64) = @splat(-2.0); + const c0: @Vector(vec_len, f64) = @splat(0x1.555555555554ep-3); + const c1: @Vector(vec_len, f64) = @splat(0x1.3333333337233p-4); + const c2: @Vector(vec_len, f64) = @splat(0x1.6db6db67f6d9fp-5); + const c3: @Vector(vec_len, f64) = @splat(0x1.f1c71fbd29fbbp-6); + const c4: @Vector(vec_len, f64) = @splat(0x1.6e8b264d467d6p-6); + const c5: @Vector(vec_len, f64) = @splat(0x1.1c5997c357e9dp-6); + const c6: @Vector(vec_len, f64) = @splat(0x1.c86a22cd9389dp-7); + const c7: @Vector(vec_len, f64) = @splat(0x1.856073c22ebbep-7); + const c8: @Vector(vec_len, f64) = @splat(0x1.fd1151acb6bedp-8); + const c9: @Vector(vec_len, f64) = @splat(0x1.087182f799c1dp-6); + const c10: @Vector(vec_len, f64) = @splat(-0x1.6602748120927p-7); + const c11: @Vector(vec_len, f64) = @splat(0x1.cfa0dd1f9478p-6); + + const ax = @abs(x); + const ax_lt_half = ax < half; + const z2 = @select(f64, ax_lt_half, x * x, @mulAdd(@Vector(vec_len, f64), -half, ax, half)); + const z = @select(f64, ax_lt_half, ax, @sqrt(z2)); + const z3 = z2 * z; + const z4 = z2 * z2; + const z8 = z4 * z4; + const p0_1 = @mulAdd(@Vector(vec_len, f64), z2, c1, c0); + const p2_3 = @mulAdd(@Vector(vec_len, f64), z2, c3, c2); + const p0_3 = @mulAdd(@Vector(vec_len, f64), z4, p2_3, p0_1); + const p4_5 = @mulAdd(@Vector(vec_len, f64), z2, c5, c4); + const p6_7 = @mulAdd(@Vector(vec_len, f64), z2, c7, c6); + const p4_7 = @mulAdd(@Vector(vec_len, f64), z4, p6_7, p4_5); + const p8_9 = @mulAdd(@Vector(vec_len, f64), z2, c9, c8); + const p10_11 = @mulAdd(@Vector(vec_len, f64), z2, c11, c10); + const p8_11 = @mulAdd(@Vector(vec_len, f64), z4, p10_11, p8_9); + const p4_11 = @mulAdd(@Vector(vec_len, f64), z8, p8_11, p4_7); + const p0_11 = @mulAdd(@Vector(vec_len, f64), z8, p4_11, p0_3); + const p = @mulAdd(@Vector(vec_len, f64), z3, p0_11, z); + const y = @select(f64, ax_lt_half, p, @mulAdd(@Vector(vec_len, f64), p, neg_two, pi_over_2)); + return @select(f64, x < zero, -y, y); +} + +test "asinBinary32Vec.special" { + const input: @Vector(9, f32) = .{ + 0x1p+0, + -0x1p+0, + 0x0p+0, + -0x0p+0, + 0x1.000002p+0, + -0x1.000002p+0, + math.inf(f32), + -math.inf(f32), + math.nan(f32), + }; + const output = asinBinary32Vec(9, input); + try testing.expectApproxEqAbs(0x1.921fb6p+0, output[0], math.floatEpsAt(f32, 0x1.921fb6p+0)); + try testing.expectApproxEqAbs(-0x1.921fb6p+0, output[1], math.floatEpsAt(f32, -0x1.921fb6p+0)); + try testing.expectEqual(0x0p+0, output[2]); + try testing.expectEqual(0x0p+0, output[3]); + try testing.expect(math.isNan(output[4])); + try testing.expect(math.isNan(output[5])); + try testing.expect(math.isNan(output[6])); + try testing.expect(math.isNan(output[7])); + try testing.expect(math.isNan(output[8])); +} + +test "asinBinary32Vec" { + const input: @Vector(10, f32) = .{ + -0x1.4c2906p-4, + 0x1.05fcfap-1, + 0x1.fab976p-2, + 0x1.8b4b8cp-1, + 0x1.7117c2p-1, + 0x1.e5e112p-5, + -0x1.07673p-2, + -0x1.2108dep-2, + -0x1.4e6e6cp-1, + 0x1.22a16ap-1, + }; + const output = asinBinary32Vec(10, input); + try testing.expectApproxEqAbs(-0x1.4c868p-4, output[0], math.floatEpsAt(f32, -0x1.4c868p-4)); + try testing.expectApproxEqAbs(0x1.130648p-1, output[1], math.floatEpsAt(f32, 0x1.130648p-1)); + try testing.expectApproxEqAbs(0x1.090abcp-1, output[2], math.floatEpsAt(f32, 0x1.090abcp-1)); + try testing.expectApproxEqAbs(0x1.c39fa2p-1, output[3], math.floatEpsAt(f32, 0x1.c39fa2p-1)); + try testing.expectApproxEqAbs(0x1.9c332p-1, output[4], math.floatEpsAt(f32, 0x1.9c332p-1)); + try testing.expectApproxEqAbs(0x1.e62a1cp-5, output[5], math.floatEpsAt(f32, 0x1.e62a1cp-5)); + try testing.expectApproxEqAbs(-0x1.0a65dep-2, output[6], math.floatEpsAt(f32, -0x1.0a65dep-2)); + try testing.expectApproxEqAbs(-0x1.25046p-2, output[7], math.floatEpsAt(f32, -0x1.25046p-2)); + try testing.expectApproxEqAbs(-0x1.6c6f0cp-1, output[8], math.floatEpsAt(f32, -0x1.6c6f0cp-1)); + try testing.expectApproxEqAbs(0x1.350f7ap-1, output[9], math.floatEpsAt(f32, 0x1.350f7ap-1)); +} + +test "asinBinary64Vec.special" { + const input: @Vector(9, f64) = .{ + 0x1p+0, + -0x1p+0, + 0x0p+0, + -0x0p+0, + 0x1.000002p+0, + -0x1.000002p+0, + math.inf(f64), + -math.inf(f64), + math.nan(f64), + }; + const output = asinBinary64Vec(9, input); + try testing.expectApproxEqAbs(0x1.921fb54442d18p+0, output[0], math.floatEpsAt(f64, 0x1.921fb54442d18p+0)); + try testing.expectApproxEqAbs(-0x1.921fb54442d18p+0, output[1], math.floatEpsAt(f64, -0x1.921fb54442d18p+0)); + try testing.expectEqual(0x0p+0, output[2]); + try testing.expectEqual(0x0p+0, output[3]); + try testing.expect(math.isNan(output[4])); + try testing.expect(math.isNan(output[5])); + try testing.expect(math.isNan(output[6])); + try testing.expect(math.isNan(output[7])); + try testing.expect(math.isNan(output[8])); +} + +test "asinBinary64Vec" { + const input: @Vector(10, f64) = .{ + 0x1.e674fba3e40d5p-2, + -0x1.30fd0566fd979p-1, + 0x1.6444a25abfeaap-2, + 0x1.40a53228d1a13p-1, + -0x1.ccc6d64845cfdp-1, + -0x1.94bd91b7fc74bp-1, + -0x1.8d741b5797fccp-2, + -0x1.3e8e7e15881c5p-3, + -0x1.88222d8ab8ca9p-2, + -0x1.41c0e9babcbd2p-2, + }; + const output = asinBinary64Vec(10, input); + try testing.expectApproxEqAbs(0x1.fae86c5941692p-2, output[0], math.floatEpsAt(f64, 0x1.fae86c5941692p-2)); + try testing.expectApproxEqAbs(-0x1.46b6ad730c93ap-1, output[1], math.floatEpsAt(f64, -0x1.46b6ad730c93ap-1)); + try testing.expectApproxEqAbs(0x1.6be0be8074eep-2, output[2], math.floatEpsAt(f64, 0x1.6be0be8074eep-2)); + try testing.expectApproxEqAbs(0x1.5a7e98f53f717p-1, output[3], math.floatEpsAt(f64, 0x1.5a7e98f53f717p-1)); + try testing.expectApproxEqAbs(-0x1.1ea2602d14e8p0, output[4], math.floatEpsAt(f64, -0x1.1ea2602d14e8p0)); + try testing.expectApproxEqAbs(-0x1.d2c2634193158p-1, output[5], math.floatEpsAt(f64, -0x1.d2c2634193158p-1)); + try testing.expectApproxEqAbs(-0x1.982d5f1895d2p-2, output[6], math.floatEpsAt(f64, -0x1.982d5f1895d2p-2)); + try testing.expectApproxEqAbs(-0x1.3fdaf7dfdc864p-3, output[7], math.floatEpsAt(f64, -0x1.3fdaf7dfdc864p-3)); + try testing.expectApproxEqAbs(-0x1.9269540735b7bp-2, output[8], math.floatEpsAt(f64, -0x1.9269540735b7bp-2)); + try testing.expectApproxEqAbs(-0x1.474c4c6625527p-2, output[9], math.floatEpsAt(f64, -0x1.474c4c6625527p-2)); +}