diff options
| author | Jordan Lewis <jordanthelewis@gmail.com> | 2022-12-28 14:27:18 -0500 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2023-01-03 13:30:24 +0200 |
| commit | 1ec74f1b70607a17829277e846ea19be6aed1fc1 (patch) | |
| tree | fce91f172fe18842908aca8a8edb12969e62c6a9 /lib/std/math.zig | |
| parent | fc07e1a2670970084bfaac726428f6f3392abf30 (diff) | |
| download | zig-1ec74f1b70607a17829277e846ea19be6aed1fc1.tar.gz zig-1ec74f1b70607a17829277e846ea19be6aed1fc1.zip | |
math: implement absInt for integer vectors
This commit adds support to absInt for integer vectors.
Diffstat (limited to 'lib/std/math.zig')
| -rw-r--r-- | lib/std/math.zig | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/lib/std/math.zig b/lib/std/math.zig index 00f86fab1b..c8eff2362e 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -784,15 +784,31 @@ fn testOverflow() !void { /// See also: `absCast` pub fn absInt(x: anytype) !@TypeOf(x) { const T = @TypeOf(x); - comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt - comptime assert(@typeInfo(T).Int.signedness == .signed); // must pass a signed integer to absInt - - if (x == minInt(T)) { - return error.Overflow; - } else { - @setRuntimeSafety(false); - return if (x < 0) -x else x; - } + return switch (@typeInfo(T)) { + .Int => |info| { + comptime assert(info.signedness == .signed); // must pass a signed integer to absInt + if (x == minInt(T)) { + return error.Overflow; + } else { + @setRuntimeSafety(false); + return if (x < 0) -x else x; + } + }, + .Vector => |vinfo| blk: { + switch (@typeInfo(vinfo.child)) { + .Int => |info| { + comptime assert(info.signedness == .signed); // must pass a signed integer to absInt + if (@reduce(.Or, x == @splat(vinfo.len, @as(vinfo.child, minInt(vinfo.child))))) { + return error.Overflow; + } + const zero = @splat(vinfo.len, @as(vinfo.child, 0)); + break :blk @select(vinfo.child, x > zero, x, -x); + }, + else => @compileError("Expected vector of ints, found " ++ @typeName(T)), + } + }, + else => @compileError("Expected an int or vector, found " ++ @typeName(T)), + }; } test "absInt" { @@ -802,6 +818,10 @@ test "absInt" { fn testAbsInt() !void { try testing.expect((absInt(@as(i32, -10)) catch unreachable) == 10); try testing.expect((absInt(@as(i32, 10)) catch unreachable) == 10); + try testing.expectEqual(@Vector(3, i32){ 10, 10, 0 }, (absInt(@Vector(3, i32){ -10, 10, 0 }) catch unreachable)); + + try testing.expectError(error.Overflow, absInt(@as(i32, minInt(i32)))); + try testing.expectError(error.Overflow, absInt(@Vector(3, i32){ 10, -10, minInt(i32) })); } /// Divide numerator by denominator, rounding toward zero. Returns an |
