| ... | ... | @@ -1875,3 +1875,39 @@ test sign { |
| 1875 | 1875 | try testSign(); |
| 1876 | 1876 | try comptime testSign(); |
| 1877 | 1877 | } |
| 1878 | |
| 1879 | /// Increases the bit width of an integer by copying the most significant bit. |
| 1880 | /// This results in the input and output having the same arithmetic value, when |
| 1881 | /// interpreted as two's complement integers. |
| 1882 | fn signExtend(To: type, n: anytype) To { |
| 1883 | const From = @TypeOf(n); |
| 1884 | if (From == u0) return 0; |
| 1885 | const FromSigned = @Int(.signed, @typeInfo(From).int.bits); |
| 1886 | const ToSigned = @Int(.signed, @typeInfo(To).int.bits); |
| 1887 | |
| 1888 | return @bitCast(@as(ToSigned, @as(FromSigned, @bitCast(n)))); |
| 1889 | } |
| 1890 | |
| 1891 | test signExtend { |
| 1892 | const number: u8 = 0x86; |
| 1893 | try testing.expectEqual(0xff86, signExtend(u16, number)); |
| 1894 | |
| 1895 | try testing.expectEqual(0, signExtend(u1, @as(u0, 0))); |
| 1896 | try testing.expectEqual(0, signExtend(u16, @as(u0, 0))); |
| 1897 | |
| 1898 | try testing.expectEqual(0x0000, signExtend(u16, @as(u1, 0b0))); |
| 1899 | try testing.expectEqual(0xffff, signExtend(u16, @as(u1, 0b1))); |
| 1900 | |
| 1901 | try testing.expectEqual(0b000, signExtend(u3, @as(u2, 0b00))); |
| 1902 | try testing.expectEqual(0b001, signExtend(u3, @as(u2, 0b01))); |
| 1903 | try testing.expectEqual(0b110, signExtend(u3, @as(u2, 0b10))); |
| 1904 | try testing.expectEqual(0b111, signExtend(u3, @as(u2, 0b11))); |
| 1905 | try testing.expectEqual(0b0000_0001, signExtend(u8, @as(u2, 0b01))); |
| 1906 | try testing.expectEqual(0b1111_1110, signExtend(u8, @as(u2, 0b10))); |
| 1907 | |
| 1908 | try testing.expectEqual(0x0039, signExtend(u16, @as(u8, 0x39))); |
| 1909 | try testing.expectEqual(0xff93, signExtend(u16, @as(u8, 0x93))); |
| 1910 | |
| 1911 | try testing.expectEqual(5, signExtend(i32, @as(i8, 5))); |
| 1912 | try testing.expectEqual(-123, signExtend(i16, @as(i8, -123))); |
| 1913 | } |