authorgravatar for tristesse@gmail.comfsh <tristesse@gmail.com> 2022-12-12 20:19:49+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-01-09 15:04:04-07:00
log7d0d99aac0c3e47ab4f82a43525a6f4a18334d43
tree8c6d507606b24bd1faa0e053cf41f422826d69f9
parentcdcb746cc2c96f5e968fe95a117dfc3901bd9fb9

std: fix bug in Pcg32 fill function (#13894)

The PCG32 fill function seems to have been copy-pasted from code using u64, so requesting `n` bytes where `(n & 7) > 4` bytes would cause the last few bytes to be all 0.

1 files changed, 10 insertions(+), 6 deletions(-)

lib/std/rand/Pcg.zig+10-6
...@@ -51,7 +51,7 @@ fn seedTwo(self: *Pcg, init_s: u64, init_i: u64) void {...@@ -51,7 +51,7 @@ fn seedTwo(self: *Pcg, init_s: u64, init_i: u64) void {
5151
52pub fn fill(self: *Pcg, buf: []u8) void {52pub fn fill(self: *Pcg, buf: []u8) void {
53 var i: usize = 0;53 var i: usize = 0;
54 const aligned_len = buf.len - (buf.len & 7);54 const aligned_len = buf.len - (buf.len & 3);
5555
56 // Complete 4 byte segments.56 // Complete 4 byte segments.
57 while (i < aligned_len) : (i += 4) {57 while (i < aligned_len) : (i += 4) {
...@@ -108,11 +108,15 @@ test "pcg fill" {...@@ -108,11 +108,15 @@ test "pcg fill" {
108 3247963454,108 3247963454,
109 };109 };
110110
111 for (seq) |s| {111 var i: u32 = 0;
112 var buf0: [4]u8 = undefined;112 while (i < seq.len) : (i += 2) {
113 var buf1: [3]u8 = undefined;113 var buf0: [8]u8 = undefined;
114 std.mem.writeIntLittle(u32, &buf0, s);114 std.mem.writeIntLittle(u32, buf0[0..4], seq[i]);
115 std.mem.writeIntLittle(u32, buf0[4..8], seq[i + 1]);
116
117 var buf1: [7]u8 = undefined;
115 r.fill(&buf1);118 r.fill(&buf1);
116 try std.testing.expect(std.mem.eql(u8, buf0[0..3], buf1[0..]));119
120 try std.testing.expect(std.mem.eql(u8, buf0[0..7], buf1[0..]));
117 }121 }
118}122}