Licencja Creative Commons

Autorem poniższego opracowania jest dr Piotr A. Dybczyński z Instytutu Obserwatorium Astronomiczne UAM w Poznaniu.


Kostka dwudziestościenna
Kostka dwudziestościenna.

Generowanie liczb pseudolosowych w języku C


  • Najważniejszą funkcją, generującą liczby pseudolosowe (zwane dalej dla wygody acz nieprecyzyjnie losowymi) jest funkcja random(). Jej prototyp zawarty jest w pliku nagłówkowym stdlib.h
  • Funkcja jest tam opisana jako: long random(void); co oznacza, że nie ma argumentów i zwraca (losową) liczbę całkowitą typu long (aktualnie tak samo długa jak int czyli 4 bajty).
  • Zwracane liczby są z zakresu od 0 do RAND_MAX, która to stała symboliczna jest również zdefiniowana w pliku nagłówkowym stdlib.h i wynosi obecnie 2147483647 .
  • Drugą ważną funkcją jest srandom(). Jej prototyp też zawarty jest w pliku nagłówkowym stdlib.h
  • Funkcja jest tam opisana tak: void srandom(unsigned int seed);, co oznacza, że nie zwraca żadnej wartości i oczekuje argumentu w postaci liczby całkowitej typu unsigned int.
  • Argument funkcji srandom(), zwany czasami zarodkiem, zmienia sekwencję występowania liczb losowych w kolejnych wywołaniach generatora liczb losowych random().
  • Jeżeli w programie nie użyjemy funkcji srandom() lub wpiszemy jako jej argument jakąś stałą całkowitą, to każde uruchomienie programu będzie korzystało z tej samej sekwencji liczb losowych. Aby tego uniknąć często stosuje się wprowadzanie przez użytkownika jakiejś liczby jako zarodka lub lepiej, samemu wstawia się tam wartość przypadkową.
  • Często stosowaną w tym celu techniką jest uzależnienie zarodka od momentu uruchomienia programu. Np. instrukcja srandom((unsigned int)time(&czas)); najpierw wywołuje funkcję time(), podająca liczbę sekund od pewnej ustalonej epoki do chwili jej wywołania, potem następuje zamiana tej wartości na liczbę typu unsigned int i użycie jej jako zarodka (Funkcja time() jednocześnie zwraca czas i pakuje go pod adres podany jako argument).
  • Użycie funkcji time() wymaga włączenia do kodu źródłowego pliku nagłówkowego time.h, w którym zdefiniowany jest też typ time_t.
  • Więcej informacji: man 3 random, man 3 srandom, man 3 time.
  • UWAGA: w bibliotece standardowej języka C są obecne również starsze funkcje rand() i srand(), które były w standardzie ANSI. Aktualnie (grudzień 2023) są to wywołania identycznego kodu co random() i srandom() i dają dokładnie te same wyniki. Różnica jest taka, że rand() zwraca wartość int a random long int, ale to tylko różnica typu, random() daje nadal liczby pseudolosowe nie większe od RAND_MAX. Można zatem używać zamiennie jednej pary funkcji lub drugiej.




Poniżej mamy przykład programu, który po skompilowaniu i uruchomieniu wypisze 10 losowych liczb całkowitych, aktualną wartość stałej RAND_MAX oraz dziesięć losowych liczb z przedziału <0,1).


/*****************************************************************
*** Przykładowy program używający liczb losowych (z zajęć)     ***
******************************************************************
***             Piotr A. Dybczyński,  19-01-2023               ***
*****************************************************************/

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

int main(void)
{

  int i;
  time_t czas;  

  srandom( (unsigned int)time(&czas) );

  for(i=0;i<10;++i)  
     printf("%2d %12d\n", i,random() );

  printf("\nMaksymalna:  %d\n\n",RAND_MAX);


  for(i=0;i<10;++i)  
      printf("%2d %22.15f\n",i,random()/(1.0+RAND_MAX) );

  return 0;
}
 

A oto przykładowy wynik działania powyższego programu:

 0   1186171905
 1   1346901345
 2    173303298
 3   1946555255
 4    106710051
 5   2013710390
 6      3288553
 7    549045313
 8   1301775356
 9     97168418

 Maksymalna:  2147483647

 0      0.646137747447938
 1      0.020310801919550
 2      0.856692060828209
 3      0.225084894802421
 4      0.695057923439890
 5      0.634246221277863
 6      0.745298271067441
 7      0.066366050858051
 8      0.117554211523384
 9      0.663401506375521


Kostka dwunastościenna
Kostka dwunastościenna.

Zadania do wykonania:

  1. Napisać symulator rzutu symetryczną kostką dwunastościenną i dwudziestościenną.
  2. Sprawdzić, ile losowań potrzeba by uzyskać pole koła metodą Monte Carlo z dokładnością 5 cyfr znaczących.




Programowe generatory liczb pseudolosowych mają bardzo bogatą literaturę. Zainteresowanym mogę polecić np. artykuł prof. Zbigniewa Kotulskiego z czasopisma Matematyka Stosowana.


Licencja Creative Commons