rand(3)

๐ŸŽ€ rand โ€” bestie's guide to fake-random numbers ๐ŸŽ€

okay so. hi. we're doing rand(3) today, from the Library Functions Manual, and I need you to know this is the standard C library (libc, -lc) we're talking about. the actual, load-bearing, been-here-forever random number situation. grab a snack. ๐Ÿ“


โœจ NAME โœจ

rand, rand_r, srand โ€” pseudo-random number generator

like... it makes numbers that look random. pseudo. fake it till you make it energy. ๐Ÿ’…


๐Ÿ“š LIBRARY ๐Ÿ“š

Standard C library (libc, -lc)


๐ŸŒธ SYNOPSIS ๐ŸŒธ

#include <stdlib.h>

int rand(void);
void srand(unsigned int seed);

[[deprecated]] int rand_r(unsigned int *seedp);

๐Ÿ’– Feature Test Macro Requirements for glibc ๐Ÿ’–

(if you wanna know how glibc gates this stuff, check feature_test_macros(7))

rand_r():

  • Since glibc 2.24:
    • _POSIX_C_SOURCE >= 199506L
  • glibc 2.23 and earlier
    • _POSIX_C_SOURCE

so yeah, _POSIX_C_SOURCE is the vibe check you need to pass. ๐Ÿซถ


๐ŸŒˆ DESCRIPTION ๐ŸŒˆ

rand() hands you a pseudo-random integer in the range 0 to RAND_MAX inclusive โ€” that's the mathematical range [0, RAND_MAX], for the math girlies. ๐Ÿ“

srand() sets its argument as the seed for a brand new sequence of pseudo-random integers that rand() will hand back. and here's the slay: these sequences are repeatable โ€” call srand() with the same seed value and you get the same sequence. same seed, same timeline. periodt. โญ

If no seed value is provided, rand() gets automatically seeded with a value of 1. just... defaults to 1. no thoughts, head empty. ๐Ÿ™ˆ

Okay so lowkey important: rand() is not reentrant, because it uses hidden state that gets modified on every single call. That might just be the seed value used by the next call, or it might be something more elaborate โ€” nobody's telling us, it's hidden, that's the whole thing. If you want reproducible behavior in a threaded application, this state has to be made explicit. And guess what? You can do exactly that with the reentrant function rand_r(). ๐Ÿงš

Like rand(), rand_r() returns a pseudo-random integer in the range [0, RAND_MAX]. The seedp argument is a pointer to an unsigned int that gets used to store state between calls. So if rand_r() is called with the same initial value for the integer pointed to by seedp, and that value isn't modified between calls, then the same pseudo-random sequence will result. โœจ

ngl though โ€” the value pointed to by the seedp argument of rand_r() provides only a very small amount of state, so this function will be a weak pseudo-random generator. Try drand48_r(3) instead. she's stronger. ๐Ÿ’ช

๐Ÿ’ซ RETURN VALUE ๐Ÿ’ซ

  • rand() and rand_r() return a value between 0 and RAND_MAX (inclusive).
  • srand() returns no value. it's giving nothing, and that's on purpose. ๐Ÿ’€

๐Ÿ‘‘ ATTRIBUTES ๐Ÿ‘‘

For an explanation of the terms used in this section, see attributes(7).

  • Interface: rand(), rand_r(), srand()
    • Attribute: Thread safety
    • Value: MT-Safe

MT-Safe, bestie. she's safe in threads. ๐Ÿซถ


๐Ÿ”ฅ VERSIONS ๐Ÿ”ฅ

The versions of rand() and srand() in the Linux C Library use the same random number generator as random(3) and srandom(3), so the lower-order bits should be as random as the higher-order bits. iconic. no bit discrimination here.

However (and this is the part where I grab your shoulders) โ€” on older rand() implementations, and on current implementations on different systems, the lower-order bits are much less random than the higher-order bits.

๐Ÿšจ Do not use this function in applications intended to be portable when good randomness is needed. (Use random(3) instead.) ๐Ÿšจ

like if you're doing crypto-adjacent anything, close this tab. this is not the function. ๐Ÿ˜ญ


๐Ÿ“ STANDARDS ๐Ÿ“

  • rand()
  • srand()

C11, POSIX.1-2008.

  • rand_r()

POSIX.1-2008.


๐Ÿฆ‹ HISTORY ๐Ÿฆ‹

  • rand()
  • srand()

SVr4, 4.3BSD, C89, POSIX.1-2001.

  • rand_r()

POSIX.1-2001. Obsolete in POSIX.1-2008. she's retired, we still love her. ๐ŸŽ€


๐Ÿ’œ EXAMPLES ๐Ÿ’œ

POSIX.1-2001 gives the following example of an implementation of rand() and srand(), possibly useful when one needs the same sequence on two different machines. (two machines, one sequence. long distance relationship but it works.)

static unsigned long next = 1;

/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned) (next/65536) % 32768);
}

void mysrand(unsigned int seed) {
    next = seed;
}

The following program can be used to display the pseudo-random sequence produced by rand() when given a particular seed. When the seed is -1, the program uses a random seed. ๐ŸŒฑ

#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
    int           r;
    unsigned int  seed, nloops;

    if (argc != 3) {
        fprintf(stderr, "Usage: %s <seed> <nloops>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    seed = atoi(argv[1]);
    nloops = atoi(argv[2]);

    if (seed == -1) {
        seed = arc4random();
        printf("seed: %u\n", seed);
    }

    srand(seed);
    for (unsigned int j = 0; j < nloops; j++) {
        r =  rand();
        printf("%d\n", r);
    }

    exit(EXIT_SUCCESS);
}

๐Ÿ‘€ SEE ALSO ๐Ÿ‘€


and that's the whole page, bestie. this was Linux man-pages 6.20, dated 2026-02-08, for rand(3). go forth and seed responsibly. mwah. ๐Ÿ’–๐ŸŒŸ๐ŸŽ€๐Ÿซถ

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: Linux-man-pages-copyleft
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms