authorgravatar for 3575188313@qq.comZhenming-Lin <3575188313@qq.com> 2026-02-14 16:57:05+08:00
committergravatar for 3575188313@qq.comZhenming-Lin <3575188313@qq.com> 2026-02-14 16:57:05+08:00
log51509fe63bd94c2067bdc31962775ed3742b657f
tree72accfbf3909751acbeadf581273387279a97b08
parentef13a373bcce33fd74dcdf3aaa86f21a601d35ec

std.math.acos/asin: Add @Vector(?,f32) and @Vector(?,f64) support


2 files changed, 380 insertions(+), 16 deletions(-)

lib/std/math/acos.zig+192-8
...@@ -4,6 +4,12 @@...@@ -4,6 +4,12 @@
4// https://git.musl-libc.org/cgit/musl/tree/src/math/acosf.c4// https://git.musl-libc.org/cgit/musl/tree/src/math/acosf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/acos.c5// https://git.musl-libc.org/cgit/musl/tree/src/math/acos.c
6// https://git.musl-libc.org/cgit/musl/tree/src/math/acosl.c6// https://git.musl-libc.org/cgit/musl/tree/src/math/acosl.c
7//
8// Ported from ARM-software, which is licensed under the MIT license:
9// https://github.com/ARM-software/optimized-routines/blob/master/LICENSE
10//
11// https://github.com/ARM-software/optimized-routines/blob/master/math/aarch64/advsimd/acosf.c
12// https://github.com/ARM-software/optimized-routines/blob/master/math/aarch64/advsimd/acos.c
713
8const std = @import("../std.zig");14const std = @import("../std.zig");
9const math = std.math;15const math = std.math;
...@@ -17,14 +23,22 @@ const native_endian = builtin.cpu.arch.endian();...@@ -17,14 +23,22 @@ const native_endian = builtin.cpu.arch.endian();
17/// - acos(x) = nan if x < -1 or x > 123/// - acos(x) = nan if x < -1 or x > 1
18pub fn acos(x: anytype) @TypeOf(x) {24pub fn acos(x: anytype) @TypeOf(x) {
19 const T = @TypeOf(x);25 const T = @TypeOf(x);
20 return switch (T) {26 switch (@typeInfo(T)) {
21 f16 => acosBinary16(x),27 .float => |info| switch (info.bits) {
22 f32 => acosBinary32(x),28 16 => return acosBinary16(x),
23 f64 => acosBinary64(x),29 32 => return acosBinary32(x),
24 f80 => acosExtended80(x),30 64 => return acosBinary64(x),
25 f128 => acosBinary128(x),31 80 => return acosExtended80(x),
26 else => @compileError("acos not implemented for " ++ @typeName(T)),32 128 => return acosBinary128(x),
27 };33 else => comptime unreachable,
34 },
35 .vector => |info| switch (info.child) {
36 f32 => return acosBinary32Vec(info.len, x),
37 f64 => return acosBinary64Vec(info.len, x),
38 else => @compileError("unimplemented"),
39 },
40 else => comptime unreachable,
41 }
28}42}
2943
30fn approxBinary16(z: f32) f32 {44fn approxBinary16(z: f32) f32 {
...@@ -441,3 +455,173 @@ test "acosBinary128" {...@@ -441,3 +455,173 @@ test "acosBinary128" {
441 try testing.expectApproxEqAbs(0x1.513270e671db2d840f20b0186c2cp1, acosBinary128(-0x1.bf887b8c4e33cbef59993056f3dep-1), math.floatEpsAt(f128, 0x1.513270e671db2d840f20b0186c2cp1));455 try testing.expectApproxEqAbs(0x1.513270e671db2d840f20b0186c2cp1, acosBinary128(-0x1.bf887b8c4e33cbef59993056f3dep-1), math.floatEpsAt(f128, 0x1.513270e671db2d840f20b0186c2cp1));
442 try testing.expectApproxEqAbs(0x1.70851a509f0e8bfbe780aa8f29f9p0, acosBinary128(0x1.0c0f600ab6f9c84c6102942044cep-3), math.floatEpsAt(f128, 0x1.70851a509f0e8bfbe780aa8f29f9p0));456 try testing.expectApproxEqAbs(0x1.70851a509f0e8bfbe780aa8f29f9p0, acosBinary128(0x1.0c0f600ab6f9c84c6102942044cep-3), math.floatEpsAt(f128, 0x1.70851a509f0e8bfbe780aa8f29f9p0));
443}457}
458
459fn acosBinary32Vec(comptime vec_len: comptime_int, x: @Vector(vec_len, f32)) @TypeOf(x) {
460 const pi: @Vector(vec_len, f32) = @splat(math.pi);
461 const pi_over_2: @Vector(vec_len, f32) = @splat(math.pi / 2.0);
462 const zero: @Vector(vec_len, f32) = @splat(0.0);
463 const half: @Vector(vec_len, f32) = @splat(0.5);
464 const neg_one: @Vector(vec_len, f32) = @splat(-1.0);
465 const two: @Vector(vec_len, f32) = @splat(2.0);
466 const c0: @Vector(vec_len, f32) = @splat(0x1.55555ep-3);
467 const c1: @Vector(vec_len, f32) = @splat(0x1.33261ap-4);
468 const c2: @Vector(vec_len, f32) = @splat(0x1.70d7dcp-5);
469 const c3: @Vector(vec_len, f32) = @splat(0x1.b059dp-6);
470 const c4: @Vector(vec_len, f32) = @splat(0x1.3af7d8p-5);
471
472 const ax = @abs(x);
473 const ax_lt_half = ax < half;
474 const is_neg = x < zero;
475 const z2 = @select(f32, ax_lt_half, x * x, @mulAdd(@Vector(vec_len, f32), -half, ax, half));
476 const z = @select(f32, ax_lt_half, ax, @sqrt(z2));
477 const z3 = z2 * z;
478 const p3_4 = @mulAdd(@Vector(vec_len, f32), z2, c4, c3);
479 const p2_4 = @mulAdd(@Vector(vec_len, f32), z2, p3_4, c2);
480 const p1_4 = @mulAdd(@Vector(vec_len, f32), z2, p2_4, c1);
481 const p0_4 = @mulAdd(@Vector(vec_len, f32), z2, p1_4, c0);
482 const p = @mulAdd(@Vector(vec_len, f32), z3, p0_4, z);
483 const mul = @select(f32, ax_lt_half, neg_one, two);
484 const add = @select(f32, ax_lt_half, pi_over_2, @select(f32, is_neg, pi, zero));
485 return @mulAdd(@Vector(vec_len, f32), mul, @select(f32, is_neg, -p, p), add);
486}
487
488fn acosBinary64Vec(comptime vec_len: comptime_int, x: @Vector(vec_len, f64)) @TypeOf(x) {
489 const pi: @Vector(vec_len, f64) = @splat(math.pi);
490 const pi_over_2: @Vector(vec_len, f64) = @splat(math.pi / 2.0);
491 const zero: @Vector(vec_len, f64) = @splat(0.0);
492 const half: @Vector(vec_len, f64) = @splat(0.5);
493 const neg_one: @Vector(vec_len, f64) = @splat(-1.0);
494 const two: @Vector(vec_len, f64) = @splat(2.0);
495 const c0: @Vector(vec_len, f64) = @splat(0x1.555555555554ep-3);
496 const c1: @Vector(vec_len, f64) = @splat(0x1.3333333337233p-4);
497 const c2: @Vector(vec_len, f64) = @splat(0x1.6db6db67f6d9fp-5);
498 const c3: @Vector(vec_len, f64) = @splat(0x1.f1c71fbd29fbbp-6);
499 const c4: @Vector(vec_len, f64) = @splat(0x1.6e8b264d467d6p-6);
500 const c5: @Vector(vec_len, f64) = @splat(0x1.1c5997c357e9dp-6);
501 const c6: @Vector(vec_len, f64) = @splat(0x1.c86a22cd9389dp-7);
502 const c7: @Vector(vec_len, f64) = @splat(0x1.856073c22ebbep-7);
503 const c8: @Vector(vec_len, f64) = @splat(0x1.fd1151acb6bedp-8);
504 const c9: @Vector(vec_len, f64) = @splat(0x1.087182f799c1dp-6);
505 const c10: @Vector(vec_len, f64) = @splat(-0x1.6602748120927p-7);
506 const c11: @Vector(vec_len, f64) = @splat(0x1.cfa0dd1f9478p-6);
507
508 const ax = @abs(x);
509 const ax_lt_half = ax < half;
510 const is_neg = x < zero;
511 const z2 = @select(f64, ax_lt_half, x * x, @mulAdd(@Vector(vec_len, f64), -half, ax, half));
512 const z = @select(f64, ax_lt_half, ax, @sqrt(z2));
513 const z3 = z2 * z;
514 const z4 = z2 * z2;
515 const z8 = z4 * z4;
516 const p0_1 = @mulAdd(@Vector(vec_len, f64), z2, c1, c0);
517 const p2_3 = @mulAdd(@Vector(vec_len, f64), z2, c3, c2);
518 const p0_3 = @mulAdd(@Vector(vec_len, f64), z4, p2_3, p0_1);
519 const p4_5 = @mulAdd(@Vector(vec_len, f64), z2, c5, c4);
520 const p6_7 = @mulAdd(@Vector(vec_len, f64), z2, c7, c6);
521 const p4_7 = @mulAdd(@Vector(vec_len, f64), z4, p6_7, p4_5);
522 const p8_9 = @mulAdd(@Vector(vec_len, f64), z2, c9, c8);
523 const p10_11 = @mulAdd(@Vector(vec_len, f64), z2, c11, c10);
524 const p8_11 = @mulAdd(@Vector(vec_len, f64), z4, p10_11, p8_9);
525 const p4_11 = @mulAdd(@Vector(vec_len, f64), z8, p8_11, p4_7);
526 const p0_11 = @mulAdd(@Vector(vec_len, f64), z8, p4_11, p0_3);
527 const p = @mulAdd(@Vector(vec_len, f64), z3, p0_11, z);
528 const mul = @select(f64, ax_lt_half, neg_one, two);
529 const add = @select(f64, ax_lt_half, pi_over_2, @select(f64, is_neg, pi, zero));
530 return @mulAdd(@Vector(vec_len, f64), mul, @select(f64, is_neg, -p, p), add);
531}
532
533test "acosBinary32Vec.special" {
534 const input: @Vector(8, f32) = .{
535 0x0p+0,
536 -0x1p+0,
537 0x1p+0,
538 0x1.000002p+0,
539 -0x1.000002p+0,
540 math.inf(f32),
541 -math.inf(f32),
542 math.nan(f32),
543 };
544 const output = acosBinary32Vec(8, input);
545 try testing.expectApproxEqAbs(0x1.921fb6p+0, output[0], math.floatEpsAt(f32, 0x1.921fb6p+0));
546 try testing.expectApproxEqAbs(0x1.921fb6p+1, output[1], math.floatEpsAt(f32, 0x1.921fb6p+1));
547 try testing.expectEqual(0x0p+0, output[2]);
548 try testing.expect(math.isNan(output[3]));
549 try testing.expect(math.isNan(output[4]));
550 try testing.expect(math.isNan(output[5]));
551 try testing.expect(math.isNan(output[6]));
552 try testing.expect(math.isNan(output[7]));
553}
554
555test "acosBinary32Vec" {
556 const input: @Vector(10, f32) = .{
557 -0x1.13284cp-2,
558 0x1.6ca8ep-1,
559 0x1.c2ca6p-1,
560 -0x1.55f12p-1,
561 -0x1.15679ep-2,
562 -0x1.41e132p-5,
563 0x1.281b0ep-1,
564 0x1.b5ce34p-1,
565 -0x1.583482p-3,
566 -0x1.ea8224p-1,
567 };
568 const output = acosBinary32Vec(10, input);
569 try testing.expectApproxEqAbs(0x1.d7c4e6p+0, output[0], math.floatEpsAt(f32, 0x1.d7c4e6p+0));
570 try testing.expectApproxEqAbs(0x1.8e6756p-1, output[1], math.floatEpsAt(f32, 0x1.8e6756p-1));
571 try testing.expectApproxEqAbs(0x1.f9d74cp-2, output[2], math.floatEpsAt(f32, 0x1.f9d74cp-2));
572 try testing.expectApproxEqAbs(0x1.26abdcp+1, output[3], math.floatEpsAt(f32, 0x1.26abdcp+1));
573 try testing.expectApproxEqAbs(0x1.d85a44p+0, output[4], math.floatEpsAt(f32, 0x1.d85a44p+0));
574 try testing.expectApproxEqAbs(0x1.9c2f68p+0, output[5], math.floatEpsAt(f32, 0x1.9c2f68p+0));
575 try testing.expectApproxEqAbs(0x1.e881bp-1, output[6], math.floatEpsAt(f32, 0x1.e881bp-1));
576 try testing.expectApproxEqAbs(0x1.1713f6p-1, output[7], math.floatEpsAt(f32, 0x1.1713f6p-1));
577 try testing.expectApproxEqAbs(0x1.bd5accp+0, output[8], math.floatEpsAt(f32, 0x1.bd5accp+0));
578 try testing.expectApproxEqAbs(0x1.6ce7d8p+1, output[9], math.floatEpsAt(f32, 0x1.6ce7d8p+1));
579}
580
581test "acosBinary64Vec.special" {
582 const input: @Vector(8, f64) = .{
583 0x0p+0,
584 -0x1p+0,
585 0x1p+0,
586 0x1.0000000000001p+0,
587 -0x1.0000000000001p+0,
588 math.inf(f64),
589 -math.inf(f64),
590 math.nan(f64),
591 };
592 const output = acosBinary64Vec(8, input);
593 try testing.expectApproxEqAbs(0x1.921fb54442d18p+0, output[0], math.floatEpsAt(f64, 0x1.921fb54442d18p+0));
594 try testing.expectApproxEqAbs(0x1.921fb54442d18p+1, output[1], math.floatEpsAt(f64, 0x1.921fb54442d18p+1));
595 try testing.expectEqual(0x0p+0, output[2]);
596 try testing.expect(math.isNan(output[3]));
597 try testing.expect(math.isNan(output[4]));
598 try testing.expect(math.isNan(output[5]));
599 try testing.expect(math.isNan(output[6]));
600 try testing.expect(math.isNan(output[7]));
601}
602
603test "acosBinary64Vec" {
604 const input: @Vector(10, f64) = .{
605 -0x1.13284b2b5006dp-2,
606 0x1.6ca8dfb825911p-1,
607 0x1.c2ca609de7505p-1,
608 -0x1.55f11fba96889p-1,
609 -0x1.15679e27084ddp-2,
610 -0x1.41e131b093c41p-5,
611 0x1.281b0d18455f5p-1,
612 0x1.b5ce34a51b239p-1,
613 -0x1.583481079de4dp-3,
614 -0x1.ea8223103b871p-1,
615 };
616 const output = acosBinary64Vec(10, input);
617 try testing.expectApproxEqAbs(0x1.d7c4e61020905p+0, output[0], math.floatEpsAt(f64, 0x1.d7c4e61020905p+0));
618 try testing.expectApproxEqAbs(0x1.8e6756e27c366p-1, output[1], math.floatEpsAt(f64, 0x1.8e6756e27c366p-1));
619 try testing.expectApproxEqAbs(0x1.f9d748eaf956p-2, output[2], math.floatEpsAt(f64, 0x1.f9d748eaf956p-2));
620 try testing.expectApproxEqAbs(0x1.26abdc68d07aap+1, output[3], math.floatEpsAt(f64, 0x1.26abdc68d07aap+1));
621 try testing.expectApproxEqAbs(0x1.d85a44ea44fe4p+0, output[4], math.floatEpsAt(f64, 0x1.d85a44ea44fe4p+0));
622 try testing.expectApproxEqAbs(0x1.9c2f688eee8abp+0, output[5], math.floatEpsAt(f64, 0x1.9c2f688eee8abp+0));
623 try testing.expectApproxEqAbs(0x1.e881b1d4eb2a1p-1, output[6], math.floatEpsAt(f64, 0x1.e881b1d4eb2a1p-1));
624 try testing.expectApproxEqAbs(0x1.1713f567a87efp-1, output[7], math.floatEpsAt(f64, 0x1.1713f567a87efp-1));
625 try testing.expectApproxEqAbs(0x1.bd5acbe8fcc59p+0, output[8], math.floatEpsAt(f64, 0x1.bd5acbe8fcc59p+0));
626 try testing.expectApproxEqAbs(0x1.6ce7d66f628e5p+1, output[9], math.floatEpsAt(f64, 0x1.6ce7d66f628e5p+1));
627}
lib/std/math/asin.zig+188-8
...@@ -4,6 +4,12 @@...@@ -4,6 +4,12 @@
4// https://git.musl-libc.org/cgit/musl/tree/src/math/asinf.c4// https://git.musl-libc.org/cgit/musl/tree/src/math/asinf.c
5// https://git.musl-libc.org/cgit/musl/tree/src/math/asin.c5// https://git.musl-libc.org/cgit/musl/tree/src/math/asin.c
6// https://git.musl-libc.org/cgit/musl/tree/src/math/asinl.c6// https://git.musl-libc.org/cgit/musl/tree/src/math/asinl.c
7//
8// Ported from ARM-software, which is licensed under the MIT license:
9// https://github.com/ARM-software/optimized-routines/blob/master/LICENSE
10//
11// https://github.com/ARM-software/optimized-routines/blob/master/math/aarch64/advsimd/asinf.c
12// https://github.com/ARM-software/optimized-routines/blob/master/math/aarch64/advsimd/asin.c
713
8const std = @import("../std.zig");14const std = @import("../std.zig");
9const math = std.math;15const math = std.math;
...@@ -19,14 +25,22 @@ const native_endian = builtin.cpu.arch.endian();...@@ -19,14 +25,22 @@ const native_endian = builtin.cpu.arch.endian();
19/// - asin(x) = nan if x < -1 or x > 125/// - asin(x) = nan if x < -1 or x > 1
20pub fn asin(x: anytype) @TypeOf(x) {26pub fn asin(x: anytype) @TypeOf(x) {
21 const T = @TypeOf(x);27 const T = @TypeOf(x);
22 return switch (T) {28 switch (@typeInfo(T)) {
23 f16 => asinBinary16(x),29 .float => |info| switch (info.bits) {
24 f32 => asinBinary32(x),30 16 => return asinBinary16(x),
25 f64 => asinBinary64(x),31 32 => return asinBinary32(x),
26 f80 => asinExtended80(x),32 64 => return asinBinary64(x),
27 f128 => asinBinary128(x),33 80 => return asinExtended80(x),
28 else => @compileError("asin not implemented for " ++ @typeName(T)),34 128 => return asinBinary128(x),
29 };35 else => comptime unreachable,
36 },
37 .vector => |info| switch (info.child) {
38 f32 => return asinBinary32Vec(info.len, x),
39 f64 => return asinBinary64Vec(info.len, x),
40 else => @compileError("unimplemented"),
41 },
42 else => comptime unreachable,
43 }
30}44}
3145
32fn approxBinary16(z: f32) f32 {46fn approxBinary16(z: f32) f32 {
...@@ -435,3 +449,169 @@ test "asinBinary128" {...@@ -435,3 +449,169 @@ test "asinBinary128" {
435 try testing.expectApproxEqAbs(-0x1.97f1092fd94ac0fdfddae2e1222bp-1, asinBinary128(-0x1.6e210214e40edf6c8479998189d1p-1), math.floatEpsAt(f128, -0x1.97f1092fd94ac0fdfddae2e1222bp-1));449 try testing.expectApproxEqAbs(-0x1.97f1092fd94ac0fdfddae2e1222bp-1, asinBinary128(-0x1.6e210214e40edf6c8479998189d1p-1), math.floatEpsAt(f128, -0x1.97f1092fd94ac0fdfddae2e1222bp-1));
436 try testing.expectApproxEqAbs(-0x1.97b62bc5ae6512093828828325e1p-3, asinBinary128(-0x1.95061bf93ed6986a45d20f0e1064p-3), math.floatEpsAt(f128, -0x1.97b62bc5ae6512093828828325e1p-3));450 try testing.expectApproxEqAbs(-0x1.97b62bc5ae6512093828828325e1p-3, asinBinary128(-0x1.95061bf93ed6986a45d20f0e1064p-3), math.floatEpsAt(f128, -0x1.97b62bc5ae6512093828828325e1p-3));
437}451}
452
453fn asinBinary32Vec(comptime vec_len: comptime_int, x: @Vector(vec_len, f32)) @TypeOf(x) {
454 const pi_over_2: @Vector(vec_len, f32) = @splat(math.pi / 2.0);
455 const zero: @Vector(vec_len, f32) = @splat(0.0);
456 const half: @Vector(vec_len, f32) = @splat(0.5);
457 const neg_two: @Vector(vec_len, f32) = @splat(-2.0);
458 const c0: @Vector(vec_len, f32) = @splat(0x1.55555ep-3);
459 const c1: @Vector(vec_len, f32) = @splat(0x1.33261ap-4);
460 const c2: @Vector(vec_len, f32) = @splat(0x1.70d7dcp-5);
461 const c3: @Vector(vec_len, f32) = @splat(0x1.b059dp-6);
462 const c4: @Vector(vec_len, f32) = @splat(0x1.3af7d8p-5);
463
464 const ax = @abs(x);
465 const ax_lt_half = ax < half;
466 const z2 = @select(f32, ax_lt_half, x * x, @mulAdd(@Vector(vec_len, f32), -half, ax, half));
467 const z = @select(f32, ax_lt_half, ax, @sqrt(z2));
468 const z3 = z2 * z;
469 const p3_4 = @mulAdd(@Vector(vec_len, f32), z2, c4, c3);
470 const p2_4 = @mulAdd(@Vector(vec_len, f32), z2, p3_4, c2);
471 const p1_4 = @mulAdd(@Vector(vec_len, f32), z2, p2_4, c1);
472 const p0_4 = @mulAdd(@Vector(vec_len, f32), z2, p1_4, c0);
473 const p = @mulAdd(@Vector(vec_len, f32), z3, p0_4, z);
474 const y = @select(f32, ax_lt_half, p, @mulAdd(@Vector(vec_len, f32), p, neg_two, pi_over_2));
475 return @select(f32, x < zero, -y, y);
476}
477
478fn asinBinary64Vec(comptime vec_len: comptime_int, x: @Vector(vec_len, f64)) @TypeOf(x) {
479 const pi_over_2: @Vector(vec_len, f64) = @splat(math.pi / 2.0);
480 const zero: @Vector(vec_len, f64) = @splat(0.0);
481 const half: @Vector(vec_len, f64) = @splat(0.5);
482 const neg_two: @Vector(vec_len, f64) = @splat(-2.0);
483 const c0: @Vector(vec_len, f64) = @splat(0x1.555555555554ep-3);
484 const c1: @Vector(vec_len, f64) = @splat(0x1.3333333337233p-4);
485 const c2: @Vector(vec_len, f64) = @splat(0x1.6db6db67f6d9fp-5);
486 const c3: @Vector(vec_len, f64) = @splat(0x1.f1c71fbd29fbbp-6);
487 const c4: @Vector(vec_len, f64) = @splat(0x1.6e8b264d467d6p-6);
488 const c5: @Vector(vec_len, f64) = @splat(0x1.1c5997c357e9dp-6);
489 const c6: @Vector(vec_len, f64) = @splat(0x1.c86a22cd9389dp-7);
490 const c7: @Vector(vec_len, f64) = @splat(0x1.856073c22ebbep-7);
491 const c8: @Vector(vec_len, f64) = @splat(0x1.fd1151acb6bedp-8);
492 const c9: @Vector(vec_len, f64) = @splat(0x1.087182f799c1dp-6);
493 const c10: @Vector(vec_len, f64) = @splat(-0x1.6602748120927p-7);
494 const c11: @Vector(vec_len, f64) = @splat(0x1.cfa0dd1f9478p-6);
495
496 const ax = @abs(x);
497 const ax_lt_half = ax < half;
498 const z2 = @select(f64, ax_lt_half, x * x, @mulAdd(@Vector(vec_len, f64), -half, ax, half));
499 const z = @select(f64, ax_lt_half, ax, @sqrt(z2));
500 const z3 = z2 * z;
501 const z4 = z2 * z2;
502 const z8 = z4 * z4;
503 const p0_1 = @mulAdd(@Vector(vec_len, f64), z2, c1, c0);
504 const p2_3 = @mulAdd(@Vector(vec_len, f64), z2, c3, c2);
505 const p0_3 = @mulAdd(@Vector(vec_len, f64), z4, p2_3, p0_1);
506 const p4_5 = @mulAdd(@Vector(vec_len, f64), z2, c5, c4);
507 const p6_7 = @mulAdd(@Vector(vec_len, f64), z2, c7, c6);
508 const p4_7 = @mulAdd(@Vector(vec_len, f64), z4, p6_7, p4_5);
509 const p8_9 = @mulAdd(@Vector(vec_len, f64), z2, c9, c8);
510 const p10_11 = @mulAdd(@Vector(vec_len, f64), z2, c11, c10);
511 const p8_11 = @mulAdd(@Vector(vec_len, f64), z4, p10_11, p8_9);
512 const p4_11 = @mulAdd(@Vector(vec_len, f64), z8, p8_11, p4_7);
513 const p0_11 = @mulAdd(@Vector(vec_len, f64), z8, p4_11, p0_3);
514 const p = @mulAdd(@Vector(vec_len, f64), z3, p0_11, z);
515 const y = @select(f64, ax_lt_half, p, @mulAdd(@Vector(vec_len, f64), p, neg_two, pi_over_2));
516 return @select(f64, x < zero, -y, y);
517}
518
519test "asinBinary32Vec.special" {
520 const input: @Vector(9, f32) = .{
521 0x1p+0,
522 -0x1p+0,
523 0x0p+0,
524 -0x0p+0,
525 0x1.000002p+0,
526 -0x1.000002p+0,
527 math.inf(f32),
528 -math.inf(f32),
529 math.nan(f32),
530 };
531 const output = asinBinary32Vec(9, input);
532 try testing.expectApproxEqAbs(0x1.921fb6p+0, output[0], math.floatEpsAt(f32, 0x1.921fb6p+0));
533 try testing.expectApproxEqAbs(-0x1.921fb6p+0, output[1], math.floatEpsAt(f32, -0x1.921fb6p+0));
534 try testing.expectEqual(0x0p+0, output[2]);
535 try testing.expectEqual(0x0p+0, output[3]);
536 try testing.expect(math.isNan(output[4]));
537 try testing.expect(math.isNan(output[5]));
538 try testing.expect(math.isNan(output[6]));
539 try testing.expect(math.isNan(output[7]));
540 try testing.expect(math.isNan(output[8]));
541}
542
543test "asinBinary32Vec" {
544 const input: @Vector(10, f32) = .{
545 -0x1.4c2906p-4,
546 0x1.05fcfap-1,
547 0x1.fab976p-2,
548 0x1.8b4b8cp-1,
549 0x1.7117c2p-1,
550 0x1.e5e112p-5,
551 -0x1.07673p-2,
552 -0x1.2108dep-2,
553 -0x1.4e6e6cp-1,
554 0x1.22a16ap-1,
555 };
556 const output = asinBinary32Vec(10, input);
557 try testing.expectApproxEqAbs(-0x1.4c868p-4, output[0], math.floatEpsAt(f32, -0x1.4c868p-4));
558 try testing.expectApproxEqAbs(0x1.130648p-1, output[1], math.floatEpsAt(f32, 0x1.130648p-1));
559 try testing.expectApproxEqAbs(0x1.090abcp-1, output[2], math.floatEpsAt(f32, 0x1.090abcp-1));
560 try testing.expectApproxEqAbs(0x1.c39fa2p-1, output[3], math.floatEpsAt(f32, 0x1.c39fa2p-1));
561 try testing.expectApproxEqAbs(0x1.9c332p-1, output[4], math.floatEpsAt(f32, 0x1.9c332p-1));
562 try testing.expectApproxEqAbs(0x1.e62a1cp-5, output[5], math.floatEpsAt(f32, 0x1.e62a1cp-5));
563 try testing.expectApproxEqAbs(-0x1.0a65dep-2, output[6], math.floatEpsAt(f32, -0x1.0a65dep-2));
564 try testing.expectApproxEqAbs(-0x1.25046p-2, output[7], math.floatEpsAt(f32, -0x1.25046p-2));
565 try testing.expectApproxEqAbs(-0x1.6c6f0cp-1, output[8], math.floatEpsAt(f32, -0x1.6c6f0cp-1));
566 try testing.expectApproxEqAbs(0x1.350f7ap-1, output[9], math.floatEpsAt(f32, 0x1.350f7ap-1));
567}
568
569test "asinBinary64Vec.special" {
570 const input: @Vector(9, f64) = .{
571 0x1p+0,
572 -0x1p+0,
573 0x0p+0,
574 -0x0p+0,
575 0x1.000002p+0,
576 -0x1.000002p+0,
577 math.inf(f64),
578 -math.inf(f64),
579 math.nan(f64),
580 };
581 const output = asinBinary64Vec(9, input);
582 try testing.expectApproxEqAbs(0x1.921fb54442d18p+0, output[0], math.floatEpsAt(f64, 0x1.921fb54442d18p+0));
583 try testing.expectApproxEqAbs(-0x1.921fb54442d18p+0, output[1], math.floatEpsAt(f64, -0x1.921fb54442d18p+0));
584 try testing.expectEqual(0x0p+0, output[2]);
585 try testing.expectEqual(0x0p+0, output[3]);
586 try testing.expect(math.isNan(output[4]));
587 try testing.expect(math.isNan(output[5]));
588 try testing.expect(math.isNan(output[6]));
589 try testing.expect(math.isNan(output[7]));
590 try testing.expect(math.isNan(output[8]));
591}
592
593test "asinBinary64Vec" {
594 const input: @Vector(10, f64) = .{
595 0x1.e674fba3e40d5p-2,
596 -0x1.30fd0566fd979p-1,
597 0x1.6444a25abfeaap-2,
598 0x1.40a53228d1a13p-1,
599 -0x1.ccc6d64845cfdp-1,
600 -0x1.94bd91b7fc74bp-1,
601 -0x1.8d741b5797fccp-2,
602 -0x1.3e8e7e15881c5p-3,
603 -0x1.88222d8ab8ca9p-2,
604 -0x1.41c0e9babcbd2p-2,
605 };
606 const output = asinBinary64Vec(10, input);
607 try testing.expectApproxEqAbs(0x1.fae86c5941692p-2, output[0], math.floatEpsAt(f64, 0x1.fae86c5941692p-2));
608 try testing.expectApproxEqAbs(-0x1.46b6ad730c93ap-1, output[1], math.floatEpsAt(f64, -0x1.46b6ad730c93ap-1));
609 try testing.expectApproxEqAbs(0x1.6be0be8074eep-2, output[2], math.floatEpsAt(f64, 0x1.6be0be8074eep-2));
610 try testing.expectApproxEqAbs(0x1.5a7e98f53f717p-1, output[3], math.floatEpsAt(f64, 0x1.5a7e98f53f717p-1));
611 try testing.expectApproxEqAbs(-0x1.1ea2602d14e8p0, output[4], math.floatEpsAt(f64, -0x1.1ea2602d14e8p0));
612 try testing.expectApproxEqAbs(-0x1.d2c2634193158p-1, output[5], math.floatEpsAt(f64, -0x1.d2c2634193158p-1));
613 try testing.expectApproxEqAbs(-0x1.982d5f1895d2p-2, output[6], math.floatEpsAt(f64, -0x1.982d5f1895d2p-2));
614 try testing.expectApproxEqAbs(-0x1.3fdaf7dfdc864p-3, output[7], math.floatEpsAt(f64, -0x1.3fdaf7dfdc864p-3));
615 try testing.expectApproxEqAbs(-0x1.9269540735b7bp-2, output[8], math.floatEpsAt(f64, -0x1.9269540735b7bp-2));
616 try testing.expectApproxEqAbs(-0x1.474c4c6625527p-2, output[9], math.floatEpsAt(f64, -0x1.474c4c6625527p-2));
617}