std::uniform_real_distribution în C++

Produce numere cu virgulă aleatorii, distribuite uniform în intervalul [a, b).

Sintaxă
std::uniform_real_distribution<double> dist(a, b);
double x = dist(generator);

Ce face std::uniform_real_distribution

std::uniform_real_distribution<double>(a, b) dă valori reale între a (inclus) și b (exclus), cu aceeași densitate în tot intervalul. Fără argumente, intervalul este [0, 1).

Este util pentru probabilități (un eveniment cu șansa p are loc dacă dist(gen) < p), coordonate aleatorii sau simulări Monte Carlo. Afișează rezultatele cu un număr fix de zecimale.

Parametri

Parametru Descriere
a, b Intervalul [a, b).
generator La apel: un generator.

Ce returnează

La fiecare apel, un double din [a, b).

Exemple

Exemplul 1: Temperaturi aleatorii

Generatorul std::mt19937 cu seed fix produce aceleași numere pe orice compilator, dar modul în care o distribuție le transformă nu este fixat de standard. Rezultatul de mai jos este cel dat de libc++ (Clang); cu GCC sau MSVC, același seed poate da alte valori.

#include <print>
#include <random>

int main() {
    std::mt19937 gen(10);
    std::uniform_real_distribution<double> temperatura(18.0, 26.0);

    for (int zi = 1; zi <= 4; ++zi) {
        std::println("Ziua {}: {:.1f} °C", zi, temperatura(gen));
    }
}

Rezultat

Ziua 1: 20.4 °C
Ziua 2: 22.0 °C
Ziua 3: 21.5 °C
Ziua 4: 24.7 °C

Exemplul 2: Estimarea lui π (Monte Carlo)

Puncte aleatorii în pătratul 1×1: proporția celor din sfertul de cerc este aproximativ π/4. Generatorul std::mt19937 cu seed fix produce aceleași numere pe orice compilator, dar modul în care o distribuție le transformă nu este fixat de standard. Rezultatul de mai jos este cel dat de libc++ (Clang); cu GCC sau MSVC, același seed poate da alte valori.

#include <print>
#include <random>

int main() {
    std::mt19937 gen(123);
    std::uniform_real_distribution<double> coord(0.0, 1.0);

    const int total = 1'000'000;
    int in_cerc = 0;
    for (int i = 0; i < total; ++i) {
        double x = coord(gen);
        double y = coord(gen);
        if (x * x + y * y <= 1.0) {
            ++in_cerc;
        }
    }
    std::println("π ≈ {:.2f}", 4.0 * in_cerc / total);
}

Rezultat

π ≈ 3.14

Greșeli frecvente

  • Te aștepți să obții vreodată exact b: capătul de sus nu este inclus.
  • Folosești uniform_real_distribution<int>: nu compilează. Pentru întregi este uniform_int_distribution.

Comenzi înrudite

  • std::uniform_int_distribution: Transformă numerele unui generator în întregi aleatorii dintr-un interval [a, b], toate cu aceeași probabilitate.
  • std::normal_distribution: Produce numere aleatorii după distribuția normală (gaussiană, „clopotul”), cu media și abaterea standard date.
  • std::bernoulli_distribution: Produce true cu probabilitatea p și false în rest: un „da sau nu” aleatoriu, ca o monedă (eventual măsluită).
  • std::mt19937: Generatorul Mersenne Twister: numere pseudo-aleatorii rapide și de calitate, reproductibile cu un seed fix.