authorgravatar for jordanthelewis@gmail.comJordan Lewis <jordanthelewis@gmail.com> 2022-12-28 14:27:18-05:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-03 13:30:24+02:00
log1ec74f1b70607a17829277e846ea19be6aed1fc1
treefce91f172fe18842908aca8a8edb12969e62c6a9
parentfc07e1a2670970084bfaac726428f6f3392abf30

math: implement absInt for integer vectors

This commit adds support to absInt for integer vectors.

1 files changed, 29 insertions(+), 9 deletions(-)

lib/std/math.zig+29-9
...@@ -784,15 +784,31 @@ fn testOverflow() !void {...@@ -784,15 +784,31 @@ fn testOverflow() !void {
784/// See also: `absCast`784/// See also: `absCast`
785pub fn absInt(x: anytype) !@TypeOf(x) {785pub fn absInt(x: anytype) !@TypeOf(x) {
786 const T = @TypeOf(x);786 const T = @TypeOf(x);
787 comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt787 return switch (@typeInfo(T)) {
788 comptime assert(@typeInfo(T).Int.signedness == .signed); // must pass a signed integer to absInt788 .Int => |info| {
789789 comptime assert(info.signedness == .signed); // must pass a signed integer to absInt
790 if (x == minInt(T)) {790 if (x == minInt(T)) {
791 return error.Overflow;791 return error.Overflow;
792 } else {792 } else {
793 @setRuntimeSafety(false);793 @setRuntimeSafety(false);
794 return if (x < 0) -x else x;794 return if (x < 0) -x else x;
795 }795 }
796 },
797 .Vector => |vinfo| blk: {
798 switch (@typeInfo(vinfo.child)) {
799 .Int => |info| {
800 comptime assert(info.signedness == .signed); // must pass a signed integer to absInt
801 if (@reduce(.Or, x == @splat(vinfo.len, @as(vinfo.child, minInt(vinfo.child))))) {
802 return error.Overflow;
803 }
804 const zero = @splat(vinfo.len, @as(vinfo.child, 0));
805 break :blk @select(vinfo.child, x > zero, x, -x);
806 },
807 else => @compileError("Expected vector of ints, found " ++ @typeName(T)),
808 }
809 },
810 else => @compileError("Expected an int or vector, found " ++ @typeName(T)),
811 };
796}812}
797813
798test "absInt" {814test "absInt" {
...@@ -802,6 +818,10 @@ test "absInt" {...@@ -802,6 +818,10 @@ test "absInt" {
802fn testAbsInt() !void {818fn testAbsInt() !void {
803 try testing.expect((absInt(@as(i32, -10)) catch unreachable) == 10);819 try testing.expect((absInt(@as(i32, -10)) catch unreachable) == 10);
804 try testing.expect((absInt(@as(i32, 10)) catch unreachable) == 10);820 try testing.expect((absInt(@as(i32, 10)) catch unreachable) == 10);
821 try testing.expectEqual(@Vector(3, i32){ 10, 10, 0 }, (absInt(@Vector(3, i32){ -10, 10, 0 }) catch unreachable));
822
823 try testing.expectError(error.Overflow, absInt(@as(i32, minInt(i32))));
824 try testing.expectError(error.Overflow, absInt(@Vector(3, i32){ 10, -10, minInt(i32) }));
805}825}
806826
807/// Divide numerator by denominator, rounding toward zero. Returns an827/// Divide numerator by denominator, rounding toward zero. Returns an