diff --git a/lib/std/rand.zig b/lib/std/rand.zig index 8c03e57bda..01bf46102e 100644 --- a/lib/std/rand.zig +++ b/lib/std/rand.zig @@ -136,22 +136,16 @@ pub const Random = struct { pub fn uintLessThan(r: Random, comptime T: type, less_than: T) T { comptime assert(@typeInfo(T).Int.signedness == .unsigned); const bits = @typeInfo(T).Int.bits; - comptime assert(bits <= 64); // TODO: workaround: LLVM ERROR: Unsupported library call operation! assert(0 < less_than); - // Small is typically u32 - const small_bits = @divTrunc(bits + 31, 32) * 32; - const Small = std.meta.Int(.unsigned, small_bits); - // Large is typically u64 - const Large = std.meta.Int(.unsigned, small_bits * 2); // adapted from: // http://www.pcg-random.org/posts/bounded-rands.html // "Lemire's (with an extra tweak from me)" - var x: Small = r.int(Small); - var m: Large = @as(Large, x) * @as(Large, less_than); - var l: Small = @as(Small, @truncate(m)); + var x = r.int(T); + var m = math.mulWide(T, x, less_than); + var l: T = @truncate(m); if (l < less_than) { - var t: Small = -%less_than; + var t = -%less_than; if (t >= less_than) { t -= less_than; @@ -160,12 +154,12 @@ pub const Random = struct { } } while (l < t) { - x = r.int(Small); - m = @as(Large, x) * @as(Large, less_than); - l = @as(Small, @truncate(m)); + x = r.int(T); + m = math.mulWide(T, x, less_than); + l = @truncate(m); } } - return @as(T, @intCast(m >> small_bits)); + return @intCast(m >> bits); } /// Constant-time implementation off `uintAtMost`.