zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit b636906fb640a12107cd21637c2af67b8e9d6ebd (tree)
parent c150a66bfe2010be86e38f40573ffc8bdf5c2326
Author: whatisaphone <hi@whatisaph.one>
Date:   Sat, 20 Jun 2026 09:45:17 -0400

std.math: Add signExtend

Diffstat:
Mlib/std/math.zig | 36++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+), 0 deletions(-)

diff --git a/lib/std/math.zig b/lib/std/math.zig @@ -1875,3 +1875,39 @@ test sign { try testSign(); try comptime testSign(); } + +/// Increases the bit width of an integer by copying the most significant bit. +/// This results in the input and output having the same arithmetic value, when +/// interpreted as two's complement integers. +fn signExtend(To: type, n: anytype) To { + const From = @TypeOf(n); + if (From == u0) return 0; + const FromSigned = @Int(.signed, @typeInfo(From).int.bits); + const ToSigned = @Int(.signed, @typeInfo(To).int.bits); + + return @bitCast(@as(ToSigned, @as(FromSigned, @bitCast(n)))); +} + +test signExtend { + const number: u8 = 0x86; + try testing.expectEqual(0xff86, signExtend(u16, number)); + + try testing.expectEqual(0, signExtend(u1, @as(u0, 0))); + try testing.expectEqual(0, signExtend(u16, @as(u0, 0))); + + try testing.expectEqual(0x0000, signExtend(u16, @as(u1, 0b0))); + try testing.expectEqual(0xffff, signExtend(u16, @as(u1, 0b1))); + + try testing.expectEqual(0b000, signExtend(u3, @as(u2, 0b00))); + try testing.expectEqual(0b001, signExtend(u3, @as(u2, 0b01))); + try testing.expectEqual(0b110, signExtend(u3, @as(u2, 0b10))); + try testing.expectEqual(0b111, signExtend(u3, @as(u2, 0b11))); + try testing.expectEqual(0b0000_0001, signExtend(u8, @as(u2, 0b01))); + try testing.expectEqual(0b1111_1110, signExtend(u8, @as(u2, 0b10))); + + try testing.expectEqual(0x0039, signExtend(u16, @as(u8, 0x39))); + try testing.expectEqual(0xff93, signExtend(u16, @as(u8, 0x93))); + + try testing.expectEqual(5, signExtend(i32, @as(i8, 5))); + try testing.expectEqual(-123, signExtend(i16, @as(i8, -123))); +}