aboutsummaryrefslogtreecommitdiff
path: root/lib/std/math.zig
diff options
context:
space:
mode:
Diffstat (limited to 'lib/std/math.zig')
-rw-r--r--lib/std/math.zig38
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