diff options
| author | Андрей Краевский <75577902+AndrewKraevskii@users.noreply.github.com> | 2024-04-13 13:06:23 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-13 03:06:23 -0700 |
| commit | 7cc0e6d4cd5d699d5377cf47ee27a2e089d046bf (patch) | |
| tree | bacde8ab8eb49a46301c0ce3293a58166a99933b /lib/std/math | |
| parent | 4fac5bd601da12140586115dc9ddc6a92577ff6d (diff) | |
| download | zig-7cc0e6d4cd5d699d5377cf47ee27a2e089d046bf.tar.gz zig-7cc0e6d4cd5d699d5377cf47ee27a2e089d046bf.zip | |
std: fix big int llshr to respect aliasing (#19612)
Diffstat (limited to 'lib/std/math')
| -rw-r--r-- | lib/std/math/big/int.zig | 12 | ||||
| -rw-r--r-- | lib/std/math/big/int_test.zig | 13 |
2 files changed, 19 insertions, 6 deletions
diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index b564d9a99b..93ad1ccbe2 100644 --- a/lib/std/math/big/int.zig +++ b/lib/std/math/big/int.zig @@ -3776,19 +3776,19 @@ fn llshr(r: []Limb, a: []const Limb, shift: usize) void { const limb_shift = shift / limb_bits; const interior_limb_shift = @as(Log2Limb, @truncate(shift)); - var carry: Limb = 0; var i: usize = 0; while (i < a.len - limb_shift) : (i += 1) { - const src_i = a.len - i - 1; - const dst_i = src_i - limb_shift; + const dst_i = i; + const src_i = dst_i + limb_shift; const src_digit = a[src_i]; - r[dst_i] = carry | (src_digit >> interior_limb_shift); - carry = @call(.always_inline, math.shl, .{ + const src_digit_next = if (src_i + 1 < a.len) a[src_i + 1] else 0; + const carry = @call(.always_inline, math.shl, .{ Limb, - src_digit, + src_digit_next, limb_bits - @as(Limb, @intCast(interior_limb_shift)), }); + r[dst_i] = carry | (src_digit >> interior_limb_shift); } } diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig index f9d7543c2b..624bdc0b83 100644 --- a/lib/std/math/big/int_test.zig +++ b/lib/std/math/big/int_test.zig @@ -2019,6 +2019,19 @@ test "shift-right multi" { try a.shiftRight(&a, 63); try a.shiftRight(&a, 2); try testing.expect(a.eqlZero()); + + try a.set(0xffff0000eeee1111dddd2222cccc3333000000000000000000000); + try a.shiftRight(&a, 84); + const string = try a.toString( + testing.allocator, + 16, + .lower, + ); + defer testing.allocator.free(string); + try std.testing.expectEqualStrings( + string, + "ffff0000eeee1111dddd2222cccc3333", + ); } test "shift-left single" { |
