From bfd2cc5a3fb05fb45496df544a1f075606aac270 Mon Sep 17 00:00:00 2001 From: Hila Friedman Date: Tue, 17 Mar 2026 02:10:27 +0100 Subject: [PATCH] even tighter return type for `std.math.sign` (#31485) The code in #31475 does not return the "smallest integer type that fits possible values" for very small integer types, namely `u0`, `i0`, and `i1` - which all end up with a return type one bit too long. Fixed in this commit. Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31485 Reviewed-by: Andrew Kelley Co-authored-by: Hila Friedman Co-committed-by: Hila Friedman --- lib/std/math.zig | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/lib/std/math.zig b/lib/std/math.zig index 019e2f5d1a..56fd14cd33 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -1775,10 +1775,7 @@ pub const F80 = struct { fn SignOf(T: type) type { return switch (@typeInfo(T)) { .comptime_int, .comptime_float => comptime_int, - .int => |int| switch (int.signedness) { - .signed => IntFittingRange(-1, 1), - .unsigned => IntFittingRange(0, 1), - }, + .int => IntFittingRange(@max(minInt(T), -1), @min(maxInt(T), 1)), .float => IntFittingRange(-1, 1), .vector => |vec| @Vector(vec.len, SignOf(vec.child)), else => @compileError("Expected an int, float, or a vector of one, found " ++ @typeName(T)), @@ -1792,14 +1789,10 @@ fn SignOf(T: type) type { /// Branchless. pub inline fn sign(n: anytype) SignOf(@TypeOf(n)) { const T = SignOf(@TypeOf(n)); - return switch (@typeInfo(T)) { - .vector => |vec| blk: { - const zero: T = @splat(0); - const one: T = @splat(1); - break :blk @select(vec.child, n > zero, one, zero) - @select(vec.child, n < zero, one, zero); - }, - else => @as(T, @intFromBool(n > 0)) - @as(T, @intFromBool(n < 0)), - }; + const zero: T = if (@typeInfo(T) == .vector) @splat(0) else 0; + const pos: T = @intCast(@intFromBool(n > zero)); + const neg: T = @intCast(@intFromBool(n < zero)); + return pos - neg; } fn testSign() !void {