Posted on • Updated on

How to use the random number generator in Zig

A short post about using the random number generator in Zig.
For people coming from other languages, Random is an interface, that is implemented by other concrete structs to provide the functionality. For more information on how interfaces in Zig can be used , refer to this other excellent post on interfaces in Zig.

The Random interface is sort of embedded inside a concrete implementation.
The usage is as follows

const std = @import("std");
const RndGen = std.rand.DefaultPrng;

pub fn main() !void {
    var rnd = RndGen.init(0);
    var some_random_num = rnd.random().int(i32);
    std.debug.print("random number is {}", .{some_random_num});
Enter fullscreen mode Exit fullscreen mode

Previously, random was used by directly accessing a pointer to the embedded interface (rnd.random.init()). This has been updated in the current master, by an embedded function random() instead of a pointer to random.

DefaultPrng implements the Random interface and instead of calling rnd.init(i32) (which won't work), we invoke rnd.random().int.
The full list functions provided by the Random interface is listed in the std documentation

Oldest comments (7)

kristoff profile image
Loris Cro

Thank you for the post. It's also worth pointing out that interfaces are about to change and in master branch Random has already changed. Before you would grab a pointer to the random field inside your specific implementation, while now random has become a function that you call to get the random interface.

var rand_impl = std.rand.DefaultPrng.init(42);
const num = rand_impl.random().int(i32);
Enter fullscreen mode Exit fullscreen mode
gowind profile image

Yes, I read the source code. Will update the example.

dozerman profile image
doz erman

Is there a way to cap the maximum? Like get a rnd between 0 and 32?

falconerd profile image
Dylan Falconer

You can use the builtin @mod

const num = @mod(rand_impl.random().int(i32), 32);
Enter fullscreen mode Exit fullscreen mode
pyrolistical profile image

I keep forgetting if I should be holding on to a std.rand.DefaultPrng or std.rand.Random.

The correct answer is to never hold on to std.rand.Random. Always access it via .random() or else the internal seed won't be incremented and you will always get the same (ie. non-random) values

jj profile image
Juan Julián Merelo Guervós

What if you want to use a random seed?

poypoyan profile image
poypoyan • Edited

The "tradition" I am aware of is to get the "now" timestamp.

var rand = std.rand.DefaultPrng.init(@as(u64, @bitCast(std.time.milliTimestamp())));
Enter fullscreen mode Exit fullscreen mode