Numeric functions

rand#

Return a pseudo-random floating-point number in the half-open range [0, EXPR).

rand draws the next value from the interpreter’s pseudo-random number stream and scales it to 0 <= n < EXPR. The result is a regular Perl number (a double), never an integer on its own — wrap with int when you want a whole number. EXPR is optional and defaults to 1, so a bare rand yields a float in [0, 1).

Synopsis#

rand EXPR
rand

What you get back#

A double-precision float n with 0 <= n < EXPR. The upper bound is exclusive: rand(6) never returns 6, only values strictly below it. For an integer result, compose with int:

my $die = int(rand(6)) + 1;       # 1..6

The distribution is (approximately) uniform across the range. rand is a scalar operator — it returns one value per call, regardless of context.

Global state it touches#

rand consumes the interpreter’s internal PRNG state, shared with srand. Two rules follow from that:

  • Autoseeding: the first call to rand in a program automatically calls srand if you haven’t already. The seed is chosen from process-level entropy, so unseeded programs produce a different stream on every run.

  • Shared stream: every subsequent rand call — anywhere in the program, in any module — draws from the same sequence. Calling srand($seed) with a fixed seed makes that sequence deterministic and reproducible, which is what you want for test fixtures and debugging. Calling srand() with no argument re-seeds from entropy.

There is no per-thread or per-scope isolation. If you need an independent stream for one piece of code, do not use rand; reach for a dedicated generator module.

Examples#

Basic draw in [0, 1):

my $u = rand();                   # e.g. 0.4173...

Dice roll — canonical int(rand(N)) + 1 idiom:

my $roll = int(rand(6)) + 1;      # 1..6

Random element of an array:

my @colors = qw(red green blue yellow);
my $pick   = $colors[ rand @colors ];

rand @colors uses the array’s length (scalar context forced by rand’s prototype), so this works for any array size.

Reproducible stream — fix the seed for tests:

srand(42);
my @sample = map { rand() } 1..5; # same five numbers every run

One-line shuffle idiom. Readable, but biasedsort compares pairs more than once, and a one-shot rand() per comparison does not produce a uniform permutation:

my @shuffled = sort { rand() <=> 0.5 } @list;   # biased; do not use

For a fair shuffle, use List::Util::shuffle:

use List::Util qw(shuffle);
my @shuffled = shuffle @list;

Simulate a weighted coin — note the exclusive upper bound means rand() < 0.3 fires with probability exactly 0.3:

my $heads = rand() < 0.3 ? "heads" : "tails";

Edge cases#

  • EXPR is 0: treated as 1, so rand(0) behaves like rand(1). This is documented upstream behaviour and is preserved here, but it is a historical quirk — do not rely on it for new code.

  • EXPR is negative: the result is undefined in practice — you may get 0, you may get a negative float, and the behaviour is not portable across Perl versions. If you want a value in [-N, 0), write rand($n) - $n explicitly.

  • EXPR is undef: stringifies to "", numifies to 0, and therefore behaves like rand(0)rand(1). Under use warnings you get an uninitialized warning.

  • EXPR is non-numeric: the usual scalar-to-number coercion applies. rand("3abc") is rand(3) with a non-numeric warning.

  • Not cryptographically secure: rand uses a fast PRNG suitable for simulation, shuffling, and test fixtures. It is not suitable for session tokens, password salts, key material, or any security-sensitive value. For those, read from /dev/urandom directly or use Crypt::URandom / Crypt::PRNG.

  • Thread/fork behaviour: after fork, both parent and child inherit the same PRNG state and will produce the same stream unless one of them calls srand() to re-seed. A common footgun in pre-forking servers — seed in the child.

  • Large EXPR: the generator produces 48 bits of randomness per draw; for EXPR close to or above 2**48, the output is no longer finely distributed over the range. For cryptographic widths you shouldn’t be using rand anyway (see above).

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • srand — seed the PRNG explicitly for reproducibility, or re-seed in a forked child

  • int — truncate a rand result toward zero to get a uniform integer in [0, N)

  • List::Util::shuffle — fair Fisher-Yates shuffle; prefer this over the sort { rand() <=> 0.5 } idiom

  • Crypt::URandom — cryptographically-secure random bytes from the OS entropy source; use this for tokens, salts, and key material

  • Crypt::PRNG — cryptographically-secure PRNG with a rich API when you need more than raw bytes