commit 6f129c9912369d4d7e22647f98e4d88b11b77bf0 (tree)
parent 9135115573051eff58ffcf1ba0a3cce51ed0b413
Author: e4m2 <git@e4m2.com>
Date: Tue, 15 Aug 2023 11:53:48 +0200
std.rand: Accept ints with >64 bits in `uintLessThanBiased`
Diffstat:
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/lib/std/rand.zig b/lib/std/rand.zig
@@ -121,14 +121,8 @@ pub const Random = struct {
/// The results of this function may be biased.
pub fn uintLessThanBiased(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);
- if (bits <= 32) {
- return @as(T, @intCast(limitRangeBiased(u32, r.int(u32), less_than)));
- } else {
- return @as(T, @intCast(limitRangeBiased(u64, r.int(u64), less_than)));
- }
+ return limitRangeBiased(T, r.int(T), less_than);
}
/// Returns an evenly distributed random unsigned integer `0 <= i < less_than`.
@@ -438,13 +432,12 @@ pub const Random = struct {
pub fn limitRangeBiased(comptime T: type, random_int: T, less_than: T) T {
comptime assert(@typeInfo(T).Int.signedness == .unsigned);
const bits = @typeInfo(T).Int.bits;
- const T2 = std.meta.Int(.unsigned, bits * 2);
// adapted from:
// http://www.pcg-random.org/posts/bounded-rands.html
// "Integer Multiplication (Biased)"
- var m: T2 = @as(T2, random_int) * @as(T2, less_than);
- return @as(T, @intCast(m >> bits));
+ const m = math.mulWide(T, random_int, less_than);
+ return @intCast(m >> bits);
}
// Generator to extend 64-bit seed values into longer sequences.