rand(3) Library Functions Manual rand(3)

rand, rand_r, srand - generator liczb pseudolosowych

Standardowa biblioteka C (libc, -lc)

#include <stdlib.h>
int rand(void);
void srand(unsigned int seed);
[[przestarzałe]] int rand_r(unsigned int *seedp);
Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)):

rand_r():

    Od glibc 2.24:
        _POSIX_C_SOURCE >= 199506L
    glibc 2.23 i wcześniejsze
        _POSIX_C_SOURCE

Funkcja rand() zwraca pseudolosową liczbę całkowitą z zakresu pomiędzy 0 a RAND_MAX włącznie (tj. matematyczny przedział [0, RAND_MAX]).

Funkcja srand() ustawia swój argument jako wartość początkową dla nowego ciągu pseudolosowych liczb całkowitych zwracanych przez rand(). Ciągi te są powtarzalne poprzez wywołanie srand() z tą samą wartością początkową.

Jeśli nie podano wartości początkowej, funkcja rand() automatycznie ustawia tę wartość na 1.

Funkcja rand() nie jest wielobieżna, ponieważ używa ukrytego stanu, który jest modyfikowany przy każdym wywołaniu. Może to być jedynie wartość ziarna, do wykorzystania przy następnym wywołaniu albo coś bardziej złożonego. Aby uzyskać odtwarzalne zachowanie w aplikacji z wątkami, stan ten musi być jawny; można to uzyskać za pomocą funkcji wielobieżnej rand_r().

Podobnie jak rand(), rand_r() zwraca pseudolosową liczbę całkowitą z zakresu [0, RAND_MAX]. Argument seedp jest wskaźnikiem do unsigned int, która jest używana do przechowywania stanu pomiędzy wywołaniami. Jeśli rand_r() wywoła się z tą samą wartością początkową jak liczba wskazywana przez seedp, a wartość ta nie zostanie zmodyfikowana pomiędzy wywołaniami, to uzyska się tę samą sekwencję pseudolosową.

Wartość, na którą wskazuje argument seedp funkcji rand_r() zapewnia jedynie bardzo ograniczoną liczbę stanów, więc opisywana funkcja będzie bardzo słabym generatorem pseudolosowym. Można korzystać z zamiennika w postaci drand48_r(3).

Funkcje rand() i rand_r() zwracają wartość z zakresu pomiędzy 0 a RAND_MAX (włącznie). Funkcja srand() nie zwraca żadnej wartości.

Informacje o pojęciach używanych w tym rozdziale można znaleźć w podręczniku attributes(7).

Interfejs Atrybut Wartość
rand(), rand_r(), srand() Bezpieczeństwo wątkowe MT-bezpieczne

Wersje rand() i srand() w bibliotece C Linuksa korzystają z tego samego generatora liczb losowych, co random() i srandom(), więc mniej znaczące bity powinny być tak samo losowe jak bity bardziej znaczące. Jednakże, w starszych implementacjach rand() i aktualnych implementacjach na różnych systemach, bity mniej znaczące są znacznie mniej losowe niż bity bardziej znaczące. Nie należy korzystać z tej funkcji w aplikacjach, które mają być przenośne, gdy potrzebna jest dobra losowość (proszę używać w zamian random(3)).

C11, POSIX.1-2008.
POSIX.1-2008.

SVr4, 4.3BSD, C89, POSIX.1-2001.
POSIX.1-2001. Przestarzałe w POSIX.1-2008.

POSIX.1-2001 daje następujący przykład implementacji rand() i srand(), który może być przydatny, gdy potrzeba jest taka sama sekwencja na dwóch różnych komputerach.


static unsigned long next = 1;
/* RAND_MAX zakłada się jako 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}
void mysrand(unsigned int seed) {
    next = seed;
}

Poniższy program może być zastosowany do wyświetlenia sekwencji pseudolosowej utworzonej przez rand() , gdy zada się jej określone ziarno. Gdy ziarno wynosi -1, program używa losowego ziarna.


#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
    int           r;
    unsigned int  seed, nloops;
    if (argc != 3) {
        fprintf(stderr, "Użycie: %s <ziarno> <n-pętli>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    seed = atoi(argv[1]);
    nloops = atoi(argv[2]);
    if (seed == -1) {
        seed = arc4random();
        printf("ziarno: %u\n", seed);
    }
    srand(seed);
    for (unsigned int j = 0; j < nloops; j++) {
        r =  rand();
        printf("%d\n", r);
    }
    exit(EXIT_SUCCESS);
}

drand48(3), random(3)

Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl> i Michał Kułach <michal.kulach@gmail.com>

Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.

Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.

2 maja 2024 r. Linux man-pages 6.8