Jak wygenerować losowy int w C?

Czy istnieje funkcja do generowania losowej liczby int w C? Czy będę musiał korzystać z biblioteki innej firmy?

 467
Author: Cœur, 2009-05-05

24 answers

Uwaga: nie używaj rand() dla bezpieczeństwa. Jeśli potrzebujesz kryptograficznie bezpiecznego numeru, Zobacz tę odpowiedź .

#include <time.h>
#include <stdlib.h>

srand(time(NULL));   // should only be called once
int r = rand();      // returns a pseudo-random integer between 0 and RAND_MAX
 571
Author: Łukasz Lew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:36

Funkcja rand() w <stdlib.h> zwraca pseudolosową liczbę całkowitą z zakresu od 0 do RAND_MAX. Możesz użyć srand(unsigned int seed), aby ustawić ziarno.

Powszechną praktyką jest używanie operatora % w połączeniu z rand(), aby uzyskać inny zakres (choć należy pamiętać, że to nieco odrzuca jednolitość). Na przykład:

/* random int between 0 and 19 */
int r = rand() % 20;

Jeśli naprawdę zależy ci na jednolitości możesz zrobić coś takiego:

/* Returns an integer in the range [0, n).
 *
 * Uses rand(), and so is affected-by/affects the same seed.
 */
int randint(int n) {
  if ((n - 1) == RAND_MAX) {
    return rand();
  } else {
    // Supporting larger values for n would requires an even more
    // elaborate implementation that combines multiple calls to rand()
    assert (n <= RAND_MAX)

    // Chop off all of the values that would cause skew...
    int end = RAND_MAX / n; // truncate skew
    assert (end > 0);
    end *= n;

    // ... and ignore results from rand() that fall above that limit.
    // (Worst case the loop condition should succeed 50% of the time,
    // so we can expect to bail out of this loop pretty quickly.)
    int r;
    while ((r = rand()) >= end);

    return r % n;
  }
}
 212
Author: Laurence Gonsalves,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-08 22:09:14

Jeśli potrzebujesz zabezpieczyć losowe znaki lub liczby całkowite:

Jak opisano w jak bezpiecznie generować liczby losowe w różnych językach programowania , powinieneś wykonać jedną z następujących czynności:

Na przykład:

#include "sodium.h"

int foo()
{
    char myString[32];
    uint32_t myInt;

    if (sodium_init() < 0) {
        /* panic! the library couldn't be initialized, it is not safe to use */
        return 1; 
    }


    /* myString will be an array of 32 random bytes, not null-terminated */        
    randombytes_buf(myString, 32);

    /* myInt will be a random number between 0 and 9 */
    myInt = randombytes_uniform(10);
}

randombytes_uniform() jest kryptograficznie bezpieczny i bezstronny.

 40
Author: Scott Arciszewski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-18 14:28:17

Przejdźmy przez to. Najpierw używamy funkcji srand() do zalania randomizera. Zasadniczo komputer może generować liczby losowe na podstawie liczby podawanej do srand (). Jeśli podasz tę samą wartość początkową, za każdym razem generowane będą te same liczby losowe.

Dlatego musimy zalać randomizer wartością, która zawsze się zmienia. Robimy to poprzez podanie jej wartości bieżącego czasu za pomocą funkcji time ().

Teraz, kiedy wywołujemy rand (), nowy losowy numer będzie produkowany za każdym razem.

#include <stdio.h>

int random_number(int min_num, int max_num);

int main(void)
{
    printf("Min : 1 Max : 40 %d\n", random_number(1,40));
    printf("Min : 100 Max : 1000 %d\n",random_number(100,1000));
    return 0;
}

int random_number(int min_num, int max_num)
{
    int result = 0, low_num = 0, hi_num = 0;

    if (min_num < max_num)
    {
        low_num = min_num;
        hi_num = max_num + 1; // include max_num in output
    } else {
        low_num = max_num + 1; // include max_num in output
        hi_num = min_num;
    }

    srand(time(NULL));
    result = (rand() % (hi_num - low_num)) + low_num;
    return result;
}
 25
Author: Abhay Budakoti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-05 19:52:23

Jeśli potrzebujesz lepszej jakości pseudo liczb losowych niż to, co zapewnia stdlib, sprawdź Mersenne Twister. Jest też szybszy. Przykładowe implementacje są obfite, na przykład tutaj .

 24
Author: MH114,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-31 08:14:18

Standardową funkcją C jest rand(). Wystarczy rozdawać karty pasjansowi, ale to okropne. Wiele implementacji rand() odbywa cykl poprzez krótką listę liczb, a niskie bity mają krótsze cykle. Sposób, w jaki niektóre programy nazywają rand() jest okropny, a obliczanie dobrego ziarna do przekazania srand() jest trudne.

Najlepszym sposobem generowania liczb losowych w C jest użycie biblioteki innej firmy, takiej jak OpenSSL. Na przykład,

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/rand.h>

/* Random integer in [0, limit) */
unsigned int random_uint(unsigned int limit) {
    union {
        unsigned int i;
        unsigned char c[sizeof(unsigned int)];
    } u;

    do {
        if (!RAND_bytes(u.c, sizeof(u.c))) {
            fprintf(stderr, "Can't get random bytes!\n");
            exit(1);
        }
    } while (u.i < (-limit % limit)); /* u.i < (2**size % limit) */
    return u.i % limit;
}

/* Random double in [0.0, 1.0) */
double random_double() {
    union {
        uint64_t i;
        unsigned char c[sizeof(uint64_t)];
    } u;

    if (!RAND_bytes(u.c, sizeof(u.c))) {
        fprintf(stderr, "Can't get random bytes!\n");
        exit(1);
    }
    /* 53 bits / 2**53 */
    return (u.i >> 11) * (1.0/9007199254740992.0);
}

int main() {
    printf("Dice: %d\n", (int)(random_uint(6) + 1));
    printf("Double: %f\n", random_double());
    return 0;
}

Po co tyle kodu? Inne języki takie jak Java a Ruby ma funkcje dla losowych liczb całkowitych lub pływaków. OpenSSL daje tylko losowe bajty, więc staram się naśladować jak Java lub Ruby przekształci je w liczby całkowite lub pływaki.

Dla liczb całkowitych chcemy uniknąć modulo bias. Przypuśćmy, że mamy kilka losowych liczb całkowitych 4 z rand() % 10000, ale {[1] } może zwrócić tylko 0 do 32767 (jak to ma miejsce w Microsoft Windows). Każda liczba od 0 do 2767 pojawia się częściej niż każda liczba od 2768 do 9999. Aby usunąć błąd, możemy spróbować ponownie rand() podczas gdy wartość jest poniżej 2768, ponieważ wartości 30000 od 2768 do 32767 mapują równomiernie na wartości 10000 od 0 do 9999.

Dla pływaków chcemy 53 losowe bity, ponieważ double posiada 53 bity precyzji (zakładając, że jest to podwójne IEEE). Jeśli użyjemy więcej niż 53 bity, otrzymamy bias zaokrąglania. Niektórzy programiści piszą kod w stylu rand() / (double)RAND_MAX, ale rand() może zwracać tylko 31 bitów, lub tylko 15 bitów w systemie Windows.

OpenSSL ' s RAND_bytes() seeds samo w sobie, być może czytając /dev/urandom w Linuksie. Jeśli potrzebujemy wielu losowych liczb, byłoby zbyt wolno odczytać je wszystkie z /dev/urandom, ponieważ muszą być skopiowane z jądra. Szybciej jest pozwolić OpenSSL generować więcej losowych liczb z nasion.

Więcej o losowych liczbach:

 14
Author: George Koehler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-08 16:33:21

Jeśli Twój system obsługuje arc4random rodzina funkcji zalecałbym użycie ich zamiast standardowej funkcji rand.

Do rodziny arc4random należą:

uint32_t arc4random(void)
void arc4random_buf(void *buf, size_t bytes)
uint32_t arc4random_uniform(uint32_t limit)
void arc4random_stir(void)
void arc4random_addrandom(unsigned char *dat, int datlen)

arc4random zwraca losową 32-bitową niepodpisaną liczbę całkowitą.

arc4random_buf umieszcza losową zawartość w parametrze buf : void *. Ilość zawartości jest określona przez parametr bytes : size_t.

arc4random_uniform zwraca losową 32-bitową niepodpisaną liczbę całkowitą, która jest zgodna z regułą: 0 <= arc4random_uniform(limit) < limit, gdzie limit jest również niepodpisaną 32-bitowa liczba całkowita.

arc4random_stir odczytuje dane z /dev/urandom i przekazuje je do arc4random_addrandom, aby dodatkowo randomizować wewnętrzną pulę liczb losowych.

arc4random_addrandom jest używany przez arc4random_stir do wypełnienia wewnętrznej puli liczb losowych zgodnie z przekazanymi do niej danymi.

Jeśli nie masz tych funkcji, ale jesteś na Unixie, możesz użyć tego kodu:

/* This is C, not C++ */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h> /* exit */
#include <stdio.h> /* printf */

int urandom_fd = -2;

void urandom_init() {
  urandom_fd = open("/dev/urandom", O_RDONLY);

  if (urandom_fd == -1) {
    int errsv = urandom_fd;
    printf("Error opening [/dev/urandom]: %i\n", errsv);
    exit(1);
  }
}

unsigned long urandom() {
  unsigned long buf_impl;
  unsigned long *buf = &buf_impl;

  if (urandom_fd == -2) {
    urandom_init();
  }

  /* Read 4 bytes, or 32 bits into *buf, which points to buf_impl */
  read(urandom_fd, buf, sizeof(long));
  return buf_impl;
}

Funkcja urandom_init otwiera urządzenie {[13] } i umieszcza deskryptor pliku w urandom_fd.

The urandom funkcja jest zasadniczo taka sama jak wywołanie rand, z tym że jest bardziej bezpieczna i zwraca long (łatwo zmienna).

Jednak /dev/urandom może być trochę powolny, więc zaleca się, aby użyć go jako ziarna dla innego generatora liczb losowych.

Jeśli Twój system nie ma /dev/urandom, ale ma ma /dev/random lub podobny plik, możesz po prostu zmienić ścieżkę przekazaną do open w urandom_init. Wywołania i API używane w urandom_init i urandom są (wierzę) Zgodny z POSIX i jako taki powinien działać na większości, jeśli nie na wszystkich systemach zgodnych z POSIX.

Uwagi: odczyt z /dev/urandom nie zablokuje się, jeśli nie ma wystarczającej entropii, więc wartości generowane w takich okolicznościach mogą być niepewne kryptograficznie. Jeśli martwisz się o to, użyj /dev/random, który zawsze zablokuje, jeśli Entropia jest niewystarczająca.

Jeśli korzystasz z innego systemu(np. Windows), użyj rand lub jakiegoś wewnętrznego systemu Windows zależnego od platformy Nie-przenośne API.

Funkcja Wrapper dla urandom, rand, lub arc4random wywołania:

#define RAND_IMPL /* urandom(see large code block) | rand | arc4random */

int myRandom(int bottom, int top){
    return (RAND_IMPL() % (top - bottom)) + bottom;
}
 9
Author: Xenon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-05 23:41:06

STL nie istnieje dla C. Musisz zadzwonić rand, albo jeszcze lepiej, random. Są one zadeklarowane w standardowym nagłówku biblioteki stdlib.h. rand jest POSIX, {[1] } jest funkcją spec BSD.

Różnica między rand a random polega na tym, że random zwraca znacznie bardziej użyteczną 32-bitową liczbę losową, a rand zazwyczaj zwraca 16-bitową liczbę. Strony Man BSD pokazują, że dolne bity rand są cykliczne i przewidywalne, więc {[0] } jest potencjalnie bezużyteczne dla małych liczb.

 8
Author: dreamlax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-08 20:24:47

Spójrz na ISAAC (Indirection, Shift, Accumulate, Add, and Count). Jego równomiernie rozłożone i ma średnią długość cyklu 2^8295.

 7
Author: geofftnz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-04 22:18:23

Chcesz użyć rand(). Uwaga (very IMPORTANT): Upewnij się, że ustawiłeś zalążek dla funkcji rand. Jeśli nie, twoje losowe liczby są nie są naprawdę losowe . To bardzo, bardzo, bardzo ważne. Na szczęście zazwyczaj można użyć kombinacji czasomierza i daty, aby uzyskać dobre ziarno.

 4
Author: Paul Sonier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-08 20:25:27

FWIW, odpowiedź jest taka, że tak, istnieje stdlib.h funkcja o nazwie rand; Ta funkcja jest dostrojona przede wszystkim dla prędkości i rozkładu, a nie dla nieprzewidywalności. Prawie wszystkie wbudowane funkcje losowe dla różnych języków i frameworków używają tej funkcji domyślnie. Istnieją również" kryptograficzne " generatory liczb losowych, które są znacznie mniej przewidywalne, ale działają znacznie wolniej. Powinny one być używane w wszelkiego rodzaju aplikacjach związanych z bezpieczeństwem.

 4
Author: tylerl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-08 20:26:25

Jest to, miejmy nadzieję, nieco bardziej losowe niż użycie srand(time(NULL)).

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

int main(int argc, char **argv)
{
    srand((unsigned int)**main + (unsigned int)&argc + (unsigned int)time(NULL));
    srand(rand());

    for (int i = 0; i < 10; i++)
        printf("%d\n", rand());
}
 4
Author: kenorb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-08 20:27:26

STL to C++, nie C, więc nie wiem czego chcesz. Jeśli jednak chcemy C, to mamy funkcje rand() i srand():

int rand(void);

void srand(unsigned seed);

Oba są częścią ANSI C. Istnieje również funkcja random():

long random(void);

Ale z tego, co wiem, {[4] } nie jest standardowym ANSI C. biblioteka stron trzecich może nie być złym pomysłem, ale wszystko zależy od tego, jak losowy numer naprawdę trzeba wygenerować.

 3
Author: Chris Lutz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-04 22:13:27

Jest to dobry sposób, aby uzyskać losową liczbę między dwoma wybranymi liczbami.

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

    #define randnum(min, max) \
        ((rand() % (int)(((max) + 1) - (min))) + (min))

int main()
{
    srand(time(NULL));

    printf("%d\n", randnum(1, 70));
}

Wyjść za pierwszym razem: 39

Wyjście po raz drugi: 61

Wyjście po raz trzeci: 65

Możesz zmienić wartości po randnum na dowolne liczby, które wybierzesz, a to wygeneruje losową liczbę dla Ciebie pomiędzy tymi dwoma liczbami.

 3
Author: coderperson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-27 04:52:55

C Program do generowania liczb losowych od 9 do 50

#include <time.h>
#include <stdlib.h>

int main()
{
    srand(time(NULL));
    int lowerLimit = 10, upperLimit = 50;
    int r =  lowerLimit + rand() % (upperLimit - lowerLimit);
    printf("%d", r);
}

Ogólnie możemy wygenerować liczbę losową pomiędzy lowerLimit i upperLimit-1

Tj. lowerLimit jest inkluzywny lub powiedzmy r ∈ [lowerLimit, upperLimit)

 3
Author: Shivam K Thakkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-20 14:45:21

rand() jest najwygodniejszym sposobem generowania liczb losowych.

Możesz również złapać losowy numer z dowolnego serwisu internetowego, takiego jak random.org.

 2
Author: Namit Sinha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-16 17:47:08
#include <stdio.h>
#include <stdlib.h>

void main() 
{
    int visited[100];
    int randValue, a, b, vindex = 0;

    randValue = (rand() % 100) + 1;

    while (vindex < 100) {
        for (b = 0; b < vindex; b++) {
            if (visited[b] == randValue) {
                randValue = (rand() % 100) + 1;
                b = 0;
            }
        }

        visited[vindex++] = randValue;
    }

    for (a = 0; a < 100; a++)
        printf("%d ", visited[a]);
}
 2
Author: Muhammad Sadiq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-10 03:58:41
#include <stdio.h>
#include <dos.h>

int random(int range);

int main(void)
{
    printf("%d", random(10));
    return 0;
}

int random(int range)
{
    struct time t;
    int r;

    gettime(&t);
    r = t.ti_sec % range;
    return r;
}
 1
Author: Bisu vs Utsab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-28 20:16:26

Na nowoczesnych procesorach x86_64 można użyć sprzętowego generatora liczb losowych poprzez _rdrand64_step()

Przykładowy kod:

#include <immintrin.h>

uint64_t randVal;
if(!_rdrand64_step(&randVal)) {
  // Report an error here: random number generation has failed!
}
// If no error occured, randVal contains a random 64-bit number
 1
Author: Serge Rogatch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-13 19:24:43

Słysząc dobre wyjaśnienie, dlaczego używanie rand() do produkcji równomiernie rozłożonych liczb losowych w danym zakresie jest złym pomysłem, postanowiłem przyjrzeć się, jak wypaczone jest wyjście. Moja sprawa testowa to uczciwe rzucanie kośćmi. Oto kod C:

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

int main(int argc, char *argv[])
{
    int i;
    int dice[6];

    for (i = 0; i < 6; i++) 
      dice[i] = 0;
    srand(time(NULL));

    const int TOTAL = 10000000;
    for (i = 0; i < TOTAL; i++)
      dice[(rand() % 6)] += 1;

    double pers = 0.0, tpers = 0.0;
    for (i = 0; i < 6; i++) {
      pers = (dice[i] * 100.0) / TOTAL;
      printf("\t%1d  %5.2f%%\n", dice[i], pers);
      tpers += pers;
    }
    printf("\ttotal:  %6.2f%%\n", tpers);
}

A oto jego wynik:

 $ gcc -o t3 t3.c
 $ ./t3 
        1666598  16.67%     
        1668630  16.69%
        1667682  16.68%
        1666049  16.66%
        1665948  16.66%
        1665093  16.65%
        total:  100.00%
 $ ./t3     
        1667634  16.68%
        1665914  16.66%
        1665542  16.66%
        1667828  16.68%
        1663649  16.64%
        1669433  16.69%
        total:  100.00%

Nie wiem, jak jednolite potrzebujesz swoich losowych liczb, ale powyższe wydaje się wystarczająco jednolite dla większości potrzeb.

Edit: dobrym pomysłem byłoby zainicjowanie PRNG za pomocą coś lepszego niż time(NULL).

 0
Author: Mouse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-20 04:06:25

Miałem poważny problem z pseudo generatorem liczb losowych w mojej ostatniej aplikacji: powtarzalnie wywoływałem mój program C za pomocą skryptu pyhton i używałem jako zalążka następującego kodu:

srand(time(NULL))

Jednak od:

  • rand wygeneruje ten sam pseudo losowy ciąg, dając ten sam seed w srand (Zobacz man srand);
  • Jak już wspomniano, funkcja czasu zmienia się tylko z sekundy na sekundę: jeśli aplikacja zostanie uruchomiona wiele razy w ciągu tej samej sekundy, time zwróci ta sama wartość za każdym razem.

Mój program wygenerował ten sam ciąg liczb. Możesz zrobić 3 rzeczy, aby rozwiązać ten problem:

  1. Wymieszać czas wyjściowy z innymi informacjami zmieniającymi się przy uruchomieniach (w mojej aplikacji nazwa wyjścia):

    srand(time(NULL) | getHashOfString(outputName))
    

    Użyłem djb2 jako mojej funkcji hash.

  2. Zwiększ rozdzielczość czasu. Na mojej platformie, clock_gettime był dostępny, więc go używam:

    #include<time.h>
    struct timespec nanos;
    clock_gettime(CLOCK_MONOTONIC, &nanos)
    srand(nanos.tv_nsec);
    
  3. Użyj obu metod razem:

    #include<time.h>
    struct timespec nanos;
    clock_gettime(CLOCK_MONOTONIC, &nanos)
    srand(nanos.tv_nsec | getHashOfString(outputName));
    

Opcja 3 zapewnia (o ile wiem) najlepszą przypadkowość nasion, ale może tworzyć różnicę tylko przy bardzo szybkim zastosowaniu. Moim zdaniem opcja 2 to Bezpieczny zakład.

 0
Author: Koldar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-16 16:33:18

Pomimo wszystkich sugestii ludzi rand() tutaj, nie chcesz używać rand() chyba, że musisz! Liczby losowe, które rand() produkuje są często bardzo złe. Cytat ze strony podręcznika Linuksa:

Wersje rand() i srand() w Linuksowej bibliotece C używają tego samego generatora liczb losowych co random(3) i srandom(3), więc bity niższego rzędu powinny być tak samo losowe jak bity wyższego rzędu. Jednak na starszych implementacjach rand() i na obecnych implementacjach na różnych systemach, Bity niższego rzędu są znacznie mniej losowe niż bity wyższego rzędu . Nie używaj tej funkcji w aplikacjach, które mają być przenośne, gdy potrzebna jest dobra losowość. (zamiast tego użyj random(3).)

Jeśli chodzi o przenośność, random() jest również zdefiniowany przez standard POSIX już od dłuższego czasu. rand() jest starszy, pojawił się już w pierwszym POSIX.1 spec (IEEE Std 1003.1-1988), natomiast random() po raz pierwszy pojawił się w POSIX.1-2001 (IEEE Std 1003.1-2001), jednak obecny Standard POSIX jest już standardem POSIX.1-2008 (IEEE Std 1003.1-2008), który otrzymał aktualizację zaledwie rok temu (IEEE Std 1003.1-2008, edycja 2016). Więc uznałbym random() za bardzo przenośny.

POSIX.1-2001 wprowadzono również funkcje lrand48() i mrand48(), zobacz tutaj :

Ta rodzina funkcji generuje liczby pseudolosowe za pomocą liniowego algorytmu kongruencyjnego i 48-bitowej arytmetyki całkowitej.

I całkiem dobre pseudo źródło jest funkcją arc4random() dostępną w wielu systemach. Nie jest częścią żadnego oficjalnego standardu, pojawił się w BSD około 1997 roku, ale można go znaleźć na systemach takich jak Linux i macOS/iOS.

 0
Author: Mecki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-17 17:46:37

Moje minimalistyczne rozwiązanie powinno działać dla liczb losowych z zakresu [min, max). Użyj srand(time(NULL)) przed wywołaniem funkcji.

int range_rand(int min_num, int max_num) {
    if (min_num >= max_num) {
        fprintf(stderr, "min_num is greater or equal than max_num!\n"); 
    }
    return min_num + (rand() % (max_num - min_num));
} 
 -1
Author: Michał Ziobro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-16 13:47:22

Spróbuj tego, zestawiłem to z niektórych pojęć już wymienionych powyżej:

/*    
Uses the srand() function to seed the random number generator based on time value,
then returns an integer in the range 1 to max. Call this with random(n) where n is an integer, and you get an integer as a return value.
 */

int random(int max) {
    srand((unsigned) time(NULL));
    return (rand() % max) + 1;
}
 -3
Author: User,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-28 17:21:36