Serwis Edukacyjny
w I-LO w Tarnowie
obrazek

Materiały dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

Autor artykułu: mgr Jerzy Wałaszek

©2020 mgr Jerzy Wałaszek
I LO w Tarnowie

Wbudowane generatory liczb pseudolosowych

SPIS TREŚCI
Podrozdziały
Współczesne języki programowania posiadają wbudowane generatory liczb pseudolosowych udostępniające programiście swoje funkcje poprzez prosty interfejs. W tym rozdziale pokażemy, jak się z tych funkcji korzysta we własnych programach.

Pascal ( Lazarus, Free Pascal )

Inicjalizacja

Ziarno generatora pseudolosowego ( ang. random seed ) można zainicjować w języku Pascal na dwa sposoby. W pierwszym odwołujemy się bezpośrednio do zmiennej przechowującej ziarno:

randseed := nowa wartość dla ziarna pseudolosowego;

Po takiej inicjalizacji generator pseudolosowy będzie produkował zawsze ten sam ciąg liczb pseudolosowych, co można wykorzystać do prostej, amatorskiej kryptografii ( zwykłe generatory LCG nie są zalecane dla profesjonalnych systemów kryptograficznych ).

Drugi sposób wykorzystuje procedurę:

randomize;

Procedura randomize inicjuje randseed wartością odczytaną z zegara systemowego. Ponieważ zegar systemowy w komputerach IBM-PC działa niezależnie od reszty sprzętu, możemy go potraktować jako źródło wartości losowych – nie wiadomo przecież, w którym momencie zostanie wywołana procedura randomize. Procedurę tę wywołujemy zwykle tylko jeden raz na samym początku programu.

Zupełnie bez sensu jest poniższa konstrukcja programowa:

...
for i := 1 to 10 do
begin
  randomize;
  writeln ( random ( 100 ) );
end;
...

Jeśli komputer działa szybko, to zegar systemowy, z którego procedura randomize pobiera czas, nie zdąży się zmienić w pętli. Zatem w każdym obiegu pętli ziarno generatora pseudolosowego będzie inicjowane tą samą wartością. W efekcie generator wyprodukuje tę samą liczbę pseudolosową – aczkolwiek zwykle różną w kolejnych uruchomieniach programu, gdyż czas zegara będzie wtedy inny. Poniżej mamy wynik działania programu.

Wynik:
19
20
16
19
19
16
11
15
12
18

Poprawnie program powinien wyglądać tak:

...
randomize;          // inicjujemy generator pseudolosowy
...
for i := 1 to 10 do // generujemy liczby pseudolosowe
begin
  writeln ( random ( 100 ) );
end;
...

Generacja całkowitych liczb pseudolosowych

Do generacji całkowitych liczb pseudolosowych wykorzystujemy funkcję random ( n  ), która zwraca wartość pseudolosową w zakresie od 0 do n - 1. Parametr n  może być liczbą 32 bitową longint lub 64 bitową int64. Wtedy wynik funkcji również jest tego samego typu. Jeśli chcemy wygenerować liczbę pseudolosową z przedziału domkniętego [ a, b ], to stosujemy następujące wyrażenie:

a + random ( a - b + 1 )

Przykładowe programy

Uwaga:

Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich.

Przykładowy program generuje 10 liczb pseudolosowych z przedziału [ 10, 20 ] :
Pascal
// Wewnętrzny generator pseudolosowy
// Data:   17.04.2008
// (C)2020 mgr Jerzy Wałaszek
//----------------------------------

program prg;

var i : integer;

begin
  randomize;
  for i := 1 to 10 do writeln ( 10 + random ( 11 ) );
end.
Wynik:
19
20
16
19
19
16
11
15
12
18

Generacja rzeczywistych liczb pseudolosowych

Liczby rzeczywiste generuje funkcja random bez parametrów. Zwraca wtedy wartość zmiennoprzecinkową typu extended ( 20 cyfr znaczących ) z przedziału [ 0, 1 ) – od 0 domknięty do 1 otwarty.

Jeśli chcemy wygenerować pseudolosową liczbę rzeczywistą z przedziału [ a, b  ) ( a  domknięty, b  otwarty ), stosujemy wzór:

a + random * ( b - a )

Jeśli chcemy wygenerować pseudolosową liczbę rzeczywistą z przedziału ( a, b ] ( a  otwarty, b  domknięty ), stosujemy wzór:

a + ( 1 - random ) * ( b - a )

Jeśli chcemy wygenerować pseudolosową liczbę rzeczywistą z przedziału [ a, b ] ( obustronnie domknięty ), stosujemy wzór:

a + random ( 2147483647 ) / 2147483646 * ( b - a )

Jeśli chcemy wygenerować pseudolosową liczbę rzeczywistą z przedziału ( a, b  ) ( obustronnie otwarty ), stosujemy wzór:

a + ( 1 + random ( 2147483646 ) ) / 2147483647 * ( b - a )
Na początek:  podrozdziału   strony 

C++ ( Code::Blocks )

Inicjalizacja

Generator pseudolosowy jest inicjowany za pomocą funkcji:

srand ( x0 );

Funkcja srand( ) wymaga dołączenia pliku nagłówkowego cstdlib. Argument x0 zostanie użyty jako ziarno generacji liczb pseudolosowych.  Oby otrzymywać w programach bardziej losowe ciągi liczb pseudolosowych, generator inicjujemy wybraną wartością losową, np. wynikiem funkcji time( ), który zmienia się co sekundę. Funkcja time( ) wymaga dołączenia pliku nagłówkowego time.h. Na początku programu umieszczamy następujące wywołanie:

...
srand ( ( unsigned )time ( NULL ) );
...

Ponieważ czas jest zliczany niezależnie od procesów obliczeniowych komputera, nie wiadomo, w którym momencie program zostanie uruchomiony i wywołana będzie funkcja time( ). Dlatego jej wynik możemy potraktować jako losowy. Wpisanie go do ziarna generatora pseudolosowego spowoduje generowanie innej sekwencji liczb pseudolosowych przy każdym uruchomieniu programu.

Inicjalizację generatora pseudolosowego wykonujemy tylko jeden raz, zawsze na początku programu, przed generacją liczb pseudolosowych. Nie ma sensu umieszczanie wywołania funkcji srand ( time ( NULL ) ) wewnątrz pętli tworzącej kolejne liczby pseudolosowe – efekt będzie wręcz odwrotny do zamierzonego. Zobacz na podobny przykład w Pascalu!

Generacja całkowitych liczb pseudolosowych

Dostęp do kolejnych liczb pseudolosowych uzyskujemy za pomocą funkcji rand( ), która zwraca wygenerowaną przez generator liczbę pseudolosową z zakresu od 0 do RAND_MAX ( stała RAND_MAX zdefiniowana jest w pliku nagłówkowym cstdlib i ma wartość 32767 = 2 15 - 1 ). Funkcja rand( ) nie zwraca całej liczby pseudolosowej, tylko jej górne 15 bitów. Takie rozwiązanie przyjęto dlatego, iż okazuje się, że generatory LCG generują młodsze bity z mniejszymi okresami powtarzania niż okresy bitów starszych. Zwracanie starszych bitów po części niweluje tę wadę.

Jeśli wystarcza nam 15 bitowy zakres liczb pseudolosowych, to do generacji liczby pseudolosowej w przedziale [a, b] stosujemy prosty wzór:

a + rand( ) % ( b - a + 1 )

Lepszym rozwiązaniem będzie sprowadzenie wyniku rand( ) do wartości zmiennoprzecinkowej w przedziale <0, 1>, a następnie wykorzystanie tej wartości do generacji liczby pseudolosowej w przedziale całkowitym [ a, b ].

a + ( int ) ( ( ( double )rand( ) / ( double )RAND_MAX ) * ( b - a ) )

Jeśli potrzebujemy większego zakresu liczb pseudolosowych niż 15 bitów, to możemy wykorzystać funkcję rand( ) kilkakrotnie:

16 bitów: 
 ( rand( ) | ( rand( ) << 15 ) ) & 0xFFFF
20 bitów: 
 ( rand( ) | ( rand( ) << 15 ) ) & 0xFFFFF
24 bity: 
 ( rand( ) | ( rand( ) << 15 ) ) & 0xFFFFFF
32 bity: 
 ( rand( ) | ( rand( ) << 15 ) | ( rand( ) << 30 ) ) & 0xFFFFFF

Przykładowe programy

Uwaga:

Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich.

Program demonstruje sposób uzyskania 64-bitowych liczb pseudolosowych przy pomocy wbudowanego generatora pseudolosowego. Lepszym jednakże rozwiązaniem jest zaprojektowanie własnego generatora pseudolosowego o okresie 64-bitowym, ponieważ jakość tak otrzymanych liczb pseudolosowych nie jest najlepsza.
C++
// Generacja 64-bitwych liczb pseudolosowych
// Data:   18.04.2008
// (C)2020 mgr Jerzy Wałaszek
//------------------------------------------

#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <time.h>

using namespace std;

typedef unsigned long long ulong;

int main( )
{
  ulong X;
  int i;
  
  srand ( ( unsigned )time ( NULL ) );
  
  for( i = 1; i <= 20; i++ )
  {
    X = ( ulong )rand( )| ( ( ulong )rand( )<<15 )| ( ( ulong )rand( )<<30 )| ( ( ulong )rand( )<<45 )| ( ( ulong )rand( )<<60 );
    cout << setw ( 20 ) << X << endl;
  }
  cout << endl;
  return 0;
}
Wynik:
14287740268258102790
18202048344639034413
 5668028842739046048
  542349849068285525
 4472085174507448855
 5136086965452494067
   16439939500462121
15973381195178743161
11574466793181441461
14401113533160066682
16435464985454005274
 5907038298318477603
 3722099091437753545
14124984979157357723
16228289200691414138
11044688875893913486
 1226176721192551851
 3351322725318429551
14137993131048917066
 3949030839947032118

Generacja rzeczywistych liczb pseudolosowych

Do generacji rzeczywistych liczb pseudolosowych wynik funkcji rand( ) sprowadzamy do przedziału {0...1}, a następnie otrzymaną wartość wykorzystujemy do uzyskania rzeczywistej liczby pseudolosowej. Poniżej podajemy prosty sposób realizacji tego zadania.

[0, 1 )  
: ( double )rand( ) / ( double ) ( RAND_MAX + 1 )
[0, 1] 
: ( double )rand( ) / ( double ) ( RAND_MAX )
( 0, 1] 
: 1 - ( double )rand( ) / ( double ) ( RAND_MAX + 1 )
( 0, 1 ) 
: ( double ) ( 1 + rand( ) ) / ( double ) ( RAND_MAX + 2 )

Rzeczywistą liczbę pseudolosową z przedziału { 0...1 } wykorzystujemy do generacji liczby pseudolosowej w przedziale { a...b } następująco:

a + liczba_pseudolosowa{0...1} * ( b - a )

Na przykład chcemy wygenerować liczbę pseudolosową w przedziale od a  = 2.5 do b  = 4.0 włącznie. Przedział ma być domknięty, zatem potrzebujemy liczby pseudolosowej z przedziału domkniętego [ 0, 1 ]. Wzór jest następujący:

2.5 + ( double )rand( ) / ( double ) ( RAND_MAX ) * 1.5

Biblioteka generatorów liczb pseudolosowych

W języku C++ od wersji 11 istnieje cała biblioteka obiektów związanych z generacją liczb pseudolosowych. Dostęp do jej funkcji uzyskuje się po dołączeniu do programu pliku nagłówkowego <random>.

Standardowy generator liczb pseudolosowych języka C++ posiada wiele ograniczeń, z których najbardziej bolesnym jest mały zakres generowanych liczb ( 0 ... RAND_MAX, RAND_MAX = 32767 ). Oczywiście ograniczenie to można ominąć losując kilka liczb pseudolosowych i łącząc je w jedną liczbę. Jest to jednak niewygodne. W takich wypadkach pomocna może być biblioteka obiektowa random. Udostępnia ona różne generatory liczb pseudolosowych oraz różne rozkłady liczbowe. Tutaj krótko opiszemy podstawowe zasady pracy z obiektami pseudolosowymi.

Generator pseudolosowy jest klasą C++. Istnieją typy ogólne tych klas oraz typy zaadaptowane do określonych rodzajów generatorów pseudolosowych:
default_random_engine : wybrany generator pseudolosowy, który daje dobre wyniki w typowych, prostych zastosowaniach.
minstd_rand : prosty, liniowy generator multiplikatywny LCG:

x = x * 48271 % 2147483647
Zakres liczb 1 ... 2147483646.

minstd_rand0 : prosty, liniowy generator multiplikatywny LCG:

x = x * 16807 % 2147483647
Zakres liczb 1 ... 2147483646.

mt19937 : generator pseudolosowy typu Mersenne Twister. Daje w wyniku liczby 32-bitowe.
mt19937_64 : generator pseudolosowy typu Mersenne Twister. Daje w wyniku liczby 64-bitowe.
ranlux24_base   generator pseudolosowy typu Ranlux o podstawie 24-bitowej. Daje w wyniku liczby 32-bitowe.
ranlux48_base   generator pseudolosowy typu Ranlux o podstawie 48-bitowej. Daje w wyniku liczby 64-bitowe.
ranlux24   generator pseudolosowy typu Ranlux o podstawie 24-bitowej z przyspieszonym postępem. Daje w wyniku liczby 32-bitowe.
ranlux48   generator pseudolosowy typu Ranlux o podstawie 48-bitowej z przyspieszonym postępem. Daje w wyniku liczby 64-bitowe.
knuth_b   generator pseudolosowy typu Knuth-B. Daje w wyniku liczby 32 bitowe.

Każda klasa generatora posiada funkcje składowe:
( konstruktor ) : tworzy obiekt danej klasy i inicjuje jego elementy składowe tak, aby był gotowy do użytku. Jako parametr dla konstruktora przekazuje się ziarno typu całkowitego bez znaku.
min( ) : zwraca minimalną wartość generowanych liczb pseudolosowych.
max( ) : zwraca maksymalną wartość generowanych liczb pseudolosowych.
seed ( v )   inicjuje na nową wartość wewnętrzne ziarno pseudolosowe wg wartości v.
operator( )   generuje kolejną liczbę pseudolosową i zwraca ją jako wynik operatora nawiasy( ).
discard( )   generuje kolejną liczbę pseudolosową, lecz nie zwraca jej.

Zobaczmy, jak to działa w praktyce. Najpierw musisz włączyć obsługę standardu 11 języka C++ w swoim kompilatorze. Jeśli korzystasz ze środowiska Code::Blocks, to z menu wybierz opcję SettingsCompiler i w okienku dialogowym zaznacz wskazaną opcję kompilatora:

Poniższy program tworzy różne generatory liczb pseudolosowych i wyświetla informacje o zakresach generowanych przez nie liczb.

C++
// Liczby pseudolosowe
// (C)2020 mgr Jerzy Wałaszek
//---------------------------

#include <iostream>
#include <ctime>
#include <random>

using namespace std;

int main( )
{
    setlocale ( LC_ALL, "" );

    cout << "Zakresy bibliotecznych generatorów pseudolosowych" << endl
         << "-------------------------------------------------" << endl << endl;

    // Tworzymy klasy generatorów pseudolosowych

    default_random_engine dgen ( time ( NULL ) );
    minstd_rand mgen ( time ( NULL ) );
    minstd_rand0 m0gen ( time ( NULL ) );
    mt19937 mtgen ( time ( NULL ) );
    mt19937_64 mt64gen ( time ( NULL ) );
    ranlux24_base rl24gen ( time ( NULL ) );
    ranlux48_base rl48gen ( time ( NULL ) );
    knuth_b kbgen ( time ( NULL ) );

    // Wyświetlamy zakresy liczb pseudolosowych dla każdego generatora

    cout << "standardowy          : " << dgen.min( ) << " ... " << dgen.max( ) << endl;
    cout << "multiplikatywny LCG  : " << mgen.min( ) << " ... " << mgen.max( ) << endl;
    cout << "multiplikatywny LCG 0: " << m0gen.min( ) << " ... " << m0gen.max( ) << endl;
    cout << "Mersenne Twister     : " << mtgen.min( ) << " ... " << mtgen.max( ) << endl;
    cout << "Mersenne Twister 64  : " << mt64gen.min( ) << " ... " << mt64gen.max( ) << endl;
    cout << "Ranlux 24-bitowy     : " << rl24gen.min( ) << " ... " << rl24gen.max( ) << endl;
    cout << "Ranlux 48-bitowy     : " << rl48gen.min( ) << " ... " << rl48gen.max( ) << endl;
    cout << endl;

    return 0;
}
Wynik:
Zakresy bibliotecznych generatorów pseudolosowych
-------------------------------------------------

standardowy          : 1 ... 2147483646
multiplikatywny LCG : 1 ... 2147483646
multiplikatywny LCG 0: 1 ... 2147483646
Mersenne Twister    : 0 ... 4294967295
Mersenne Twister 64 : 0 ... 18446744073709551615
Ranlux 24-bitowy    : 0 ... 16777215
Ranlux 48-bitowy    : 0 ... 281474976710655

Następny program generuje 15 liczb pseudolosowych za pomocą wybranego generatora pseudolosowego. Generator możesz zmienić na inny.

C++
// Liczby pseudolosowe
// (C)2020 mgr Jerzy Wałaszek
//---------------------------

#include <iostream>
#include <ctime>
#include <random>
#include <iomanip>

using namespace std;

int main( )
{

    cout << "Generacja liczb pseudolosowych generatorem Mersenne Twister" << endl
         << "----------------------------------------------------------" << endl << endl;

    // Tworzymy generator pseudolosowy Mersenne Twister

    mt19937_64 mt64gen ( time ( NULL ) );

    // Wyświetlamy 15 liczb pseudolosowych

    for( int i = 0; i < 15; i++ ) cout << setw ( 22 ) << mt64gen( ) << endl;

    cout << endl;

    return 0;
}
Wynik:
Generacja liczb pseudolosowych generatorem Mersenne Twister
----------------------------------------------------------

  10537470712149690863
  16289189653767349705
  17446861035845780457
   8462092411226512412
  11670304320697365710
     89603159830766338
  11893928287530825151
   4391792179446479643
   5359857403735253840
    939567318540422672
   1708525228151313803
   7177467170986783977
  12812186784476095291
   9706571523780530581
  17589396534050711681

Jeśli chcesz otrzymywać liczby z zakresu A...B, to możesz zastosować podany wcześniej wzór:

A + generator( ) % ( B - A + 1 )

Istnieje jednak lepszy sposób, który wykorzystuje rozkład generowanych liczb. Rozkład określa prawdopodobieństwo pojawienia się określonej wartości w zakresie generowanych liczb. Jeśli prawdopodobieństwo każdej wartości w zakresie jest takie samo, to mamy do czynienia z rozkładem jednorodnym ( ang. uniform distribution ). Rozkład nazywamy dyskretnym, jeśli w podanym zakresie liczby mogą przyjmować tylko wybrane wartości ( np. całkowite ).

Biblioteka random udostępnia mnóstwo różnych rozkładów, których dokładne omówienie wykracza poza ramy tego artykułu.

Rozkład w bibliotece random jest klasą. Zasady użycia są następujące:

  1. Tworzymy klasę rozkładu przekazując do jej konstruktora odpowiednie parametry. Dla rozkładu jednorodnego są to granice zakresu liczb pseudolosowych.
  2. Tworzymy klasę generatora liczb pseudolosowych.
  3. Generujemy liczby pseudolosowe poprzez operator( ) klasy rozkładu przekazując w parametrze klasę generatora pseudolosowego.

Poniższy program generuje 200 liczb pseudolosowych o rozkładzie jednorodnym.

C++
// Liczby pseudolosowe
// (C)2020 mgr Jerzy Wałaszek
//---------------------------

#include <iostream>
#include <ctime>
#include <random>
#include <iomanip>

using namespace std;

int main( )
{
    setlocale ( LC_ALL, "" );

    cout << "200 liczb pseudolosowych od 1 do 999 o rozkładzie jednorodnym" << endl
         << "-------------------------------------------------------------" << endl << endl;

    // Tworzymy klasę szablonową int rozkładu jednorodnego

    uniform_int_distribution<int> dist ( 1, 999 );

    // Tworzymy standardowy generator pseudolosowy

    default_random_engine gen ( time ( NULL ) );

    // Wyświetlamy 200 liczb pseudolosowych

    int c = 0;
    for( int i = 0; i < 200; i++ )
    {
        cout << setw ( 4 ) << dist ( gen );
        c++;
        if( c == 10 )
        {
            c = 0; cout << endl;
        }
    }

    cout << endl;

    return 0;
}
Wynik:
200 liczb pseudolosowych od 1 do 999 o rozkładzie jednorodnym
-------------------------------------------------------------

 573 919  35 724 241 623 106  20  82 683
 348 233 137  86 408  63 412 421 587 607
 258  98 355 342 460 672 321 263 826 787
 566 971  51 926 816 717 123 672 934 280
 408 420 474 933 267  81 139 854 987 419
 480 307 248 827 297 164  85 819 579 958
 700 226 399 256 436 158 283 405 259 162
 122  32 698 944 703  57 552 928 498 45
 951 516 167 871 772 782 119 133 770 156
 788 844 272 726 856 927 678 644 892 503
 124 696 332 919 855 357 369 751 227 387
 956 786 707 827 193 582 829 395  10  11
 861 638 255 437  80 473 237  53 380 314
 874 728 443 586 624 196 813 612 530 778
 965 817 821 334 548 610 647 386 437 806
 781 806 756  60 961 360 142 748 270 435
 143 857 623 427 801 409 388 656 922 956
 252  54  40 442 825 103 297 195  91 642
 191 549 537 140 565 425 247 305 938 687
 132 996 955 424  24 668 189 463 479 275

Biblioteka <random> pozwala również na generowanie rzeczywistych liczb pseudolosowych za pomocą obiektów rozkładu. Przy obiekcie rozkładu uniform_real_distribution parametry a, b określają przedział [ a, b ) – domknięty lewostronnie, otwarty prawostronnie. Poniższy program generuje rzeczywiste liczby pseudolosowe z przedziału [ a, b ).

C++
// Liczby zmiennoprzecinkowe
// (C)2020 mgr Jerzy Wałaszek
//---------------------------

#include <iostream>
#include <random>
#include <ctime>
#include <iomanip>

using namespace std;

int main( )
{
    double a, b, x;

    cout << setprecision ( 5 ) << fixed;
    cout << "Zmiennoprzecinkowe liczby pseudolosowe w przedziale [ a, b )" << endl
         << "---------------------------------------------------------" << endl << endl
         << "Podaj granice:" << endl;

    // Odczytujemy granice przedziału liczb pseudolosowych

    cout << "a = ? "; cin >> a;
    cout << "b = ? "; cin >> b;
    cout << endl;

    // Tworzymy obiekt generatora pseudolosowego i inicjujemy go

    mt19937 gen ( time ( NULL ) );

    // Tworzymy klasę rozkładu:
    // Rozkład jednorodny liczb rzeczywistych w przedziale <a, b )

    uniform_real_distribution <double> dist ( a, b );

    // Generujemy 10 liczb pseudolosowych

    for( int i = 0; i < 10; i++ )
    {
        x = dist ( gen );
        cout << setw ( 12 ) << x << endl;
    }

    cout << endl;

    return 0;
}
Wynik:
Zmiennoprzecinkowe liczby pseudolosowe w przedziale [ a, b )
---------------------------------------------------------

Podaj granice:
a = ? -10
b = ? 10

    -1.49019
    -0.70826
     5.20275
     3.89604
     8.31401
     0.76755
    -7.90011
    -2.96140
     5.07277
    -3.50012
Na początek:  podrozdziału   strony 

Basic ( Free Basic )

Inicjalizacja

Ziarno generatora pseudolosowego inicjujemy za pomocą instrukcji:

Randomize X0

Aby otrzymywać przy każdym uruchomieniu programu inne sekwencje liczb pseudolosowych, jako ziarno stosuje się wartość licznika czasu:

Randomize Timer

Inicjalizację generatora pseudolosowego wykonuje się jeden raz na samym początku programu. Zobacz na odpowiednie przykłady dla języka Pascal – w Basicu jest bardzo podobnie.

Generacja całkowitych liczb pseudolosowych

W języku Basic istnieje funkcja Rnd, która zwraca tylko rzeczywistą wartość pseudolosową z przedziału [ 0, 1 ) ( lewostronnie domkniętego, prawostronnie otwartego ). Aby otrzymać liczbę pseudolosową z przedziału całkowitego [ a, b ], stosujemy następujące wyrażenie:

a + Int ( Rnd * ( b - a + 1 ) )    lub   a + Cint ( Rnd * ( b - a ) )

Przykładowe programy

Uwaga:

Zanim uruchomisz program, przeczytaj wstęp do tego artykułu, w którym wyjaśniamy funkcje tych programów oraz sposób korzystania z nich.

Program wyświetla 15 liczb pseudolosowych z przedziału całkowitego [ 20, 30 ].
Basic
' Wbudowany generator liczb pseudolosowych
' Data:   18.04.2008
' (C)2020 mgr Jerzy Wałaszek
'-----------------------------------------

Dim i As Integer

Randomize Timer

For i = 1 To 15
  Print Int ( Rnd * 11 ) + 20
Next
End
Wynik:
xxx 26
 23
 30
 28
 26
 27
 20
 27
 25
 30
 25
 27
 26
 22
 25

Generacja rzeczywistych liczb pseudolosowych

W języku Basic funkcja Rnd zwraca rzeczywistą liczbę pseudolosową z przedziału [ 0, 1 ).

Aby uzyskać rzeczywistą liczbę pseudolosową w przedziale [ a, b  ) stosujemy wyrażenie:

a + Rnd * ( b - a )

Aby uzyskać rzeczywistą liczbę pseudolosową w przedziale ( a, b ] stosujemy wyrażenie:

a + ( 1 - Rnd ) * ( b - a )

Aby uzyskać rzeczywistą liczbę pseudolosową w przedziale domkniętym [ a, b ] stosujemy konstrukcję:

If Rnd > 0.5 ) Then
    x = a + Rnd * ( b - a )
Else
    x = a + ( 1 - Rnd ) * ( b - a )
End If

Aby uzyskać rzeczywistą liczbę pseudolosową w przedziale otwartym ( a, b ) stosujemy konstrukcję:

Do
    x = a + Rnd * ( b - a )
Loop Until x <> a
Na początek:  podrozdziału   strony 

Zespół Przedmiotowy
Chemii-Fizyki-Informatyki

w I Liceum Ogólnokształcącym
im. Kazimierza Brodzińskiego
w Tarnowie
ul. Piłsudskiego 4
©2020 mgr Jerzy Wałaszek

Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone
pod warunkiem podania źródła oraz niepobierania za to pieniędzy.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.