HOWTO · C++

Comment générer un nombre aléatoire entre 0 et 1 en C++

Cet article montre comment créer un nombre aléatoire entre 0 et 1 intervalle C++

Sur cette page

Pour générer une valeur pseudo-aléatoire à virgule flottante comprise entre 0 inclus et 1 exclu, associez un moteur aléatoire de C++11 à std::uniform_real_distribution<double>. L’exemple utilise une graine fixe : sur une même implémentation, le même moteur et la même graine reproduisent une séquence. Pour tout nouveau code C++, préférez <random> ; gardez std::rand pour la maintenance d’anciens programmes.

Utiliser <random> de C++11 pour générer un nombre à virgule flottante

Incluez <random>, créez un moteur et transmettez-le à une distribution chaque fois que vous avez besoin d’une valeur. Un moteur produit une séquence de bits pseudo-aléatoires ; la distribution convertit ces bits en valeurs du type et de l’intervalle demandés. Cet exemple complet affiche cinq valeurs. Grâce à sa graine fixe, les exécutions répétées sont reproductibles avec la même implémentation de la bibliothèque standard.

#include <iostream>
#include <random>

int main() {
    std::mt19937 engine(2026);
    std::uniform_real_distribution<double> distribution(0.0, 1.0);

    for (int i = 0; i < 5; ++i) {
        std::cout << distribution(engine) << '\n';
    }
}

Les chiffres affichés dépendent de l’implémentation de la bibliothèque standard. Pour une même implémentation, utiliser le même moteur et la même graine produit la même séquence. Pour en obtenir une autre, choisissez une graine différente ou initialisez le moteur une seule fois à partir de std::random_device ; selon le système, ce dispositif peut ne pas fournir d’entropie non déterministe.

Comprendre l’intervalle de sortie et choisir un moteur

Pour std::uniform_real_distribution<double>(0.0, 1.0), l’intervalle spécifié est semi-ouvert : la valeur 0 peut être renvoyée, mais 1 est exclu. L’argument de modèle détermine le type du résultat à virgule flottante (float, double ou long double). Une distribution doit recevoir un moteur en argument : elle ne génère pas de valeurs de façon autonome.

Le moteur détermine la séquence pseudo-aléatoire, et la graine indique où cette séquence commence. std::mt19937 est un moteur standard très utilisé dont l’algorithme est spécifié. std::default_random_engine est pratique lorsque le choix précis du moteur importe peu, mais ce choix dépend de l’implémentation ; il convient donc moins si vous avez besoin de retrouver la même séquence avec différentes bibliothèques standard. Initialisez un moteur une fois, puis réutilisez-le : le réinitialiser avant chaque tirage peut faire répéter des valeurs et dégrader la séquence. Ces outils conviennent aux simulations, aux jeux et aux usages aléatoires courants, mais pas à la génération de secrets cryptographiques.

Réserver std::rand au code ancien

Les anciens programmes peuvent utiliser std::rand, déclaré dans <cstdlib>. Cette fonction renvoie un entier compris entre 0 et RAND_MAX, bornes incluses. Convertissez le résultat en nombre à virgule flottante avant la division afin d’éviter une division entière. Par exemple, l’expression intégrée static_cast<double>(std::rand()) / (static_cast<double>(RAND_MAX) + 1.0) ramène l’entier à l’intervalle souhaité.

Cette mise à l’échelle garantit un résultat inférieur à 1, même lorsque std::rand renvoie RAND_MAX. Pour faire varier les résultats d’une exécution à l’autre, appelez std::srand une seule fois avant de générer des valeurs, souvent avec une graine basée sur l’heure ; des exécutions répétées peuvent toutefois utiliser la même graine, et l’initialisation ne renforce pas la qualité du générateur. La valeur de RAND_MAX dépend de l’implémentation, et std::rand offre moins de contrôle sur le moteur et la séquence que <random>. Pour du nouveau code, préférez le moteur et la distribution de C++11 ; n’utilisez la fonction historique que lorsqu’une interface existante l’exige.