Comment générer un nombre float aléatoire en C++

Jinku Hu 12 octobre 2023
  1. Utiliser la bibliothèque C++11 <random> pour générer un nombre float aléatoire
  2. Utiliser la fonction rand pour générer un float aléatoire
Comment générer un nombre float aléatoire en C++

Cet article explique plusieurs méthodes pour générer un nombre float aléatoire en C++.

Utiliser la bibliothèque C++11 <random> pour générer un nombre float aléatoire

Cette méthode est le moyen recommandé pour générer des nombres aléatoires de haute qualité en C++ contemporain. Dans un premier temps, l’objet std::random_device doit être initialisé. Il produit des bits aléatoires non déterministes pour l’ensemencement du moteur aléatoire, ce qui est crucial pour éviter de produire les mêmes séquences de nombres. Dans cet exemple, nous utilisons std::default_random_engine pour générer des valeurs pseudo-aléatoires, mais vous pouvez déclarer un moteur d’algorithme spécifique (voir la liste complète ici). Ensuite, nous initialisons une distribution uniforme et nous passons les valeurs min/max comme arguments optionnels.

En conséquence, nous produisons 5 floats aléatoires à la console.

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

using std::cout;
using std::endl;
using std::setprecision;

constexpr int FLOAT_MIN = 10;
constexpr int FLOAT_MAX = 100;

int main() {
  std::random_device rd;
  std::default_random_engine eng(rd());
  std::uniform_real_distribution<> distr(FLOAT_MIN, FLOAT_MAX);

  for (int n = 0; n < 5; ++n) {
    cout << setprecision(10) << distr(eng) << "\n";
  }

  return EXIT_SUCCESS;
}

Production:

19.54383877
92.41870106
92.42645927
93.53035308
39.09127952

La version précédente génère en fait des valeurs en virgule float de double précision (64 bits). Vous pouvez personnaliser le type de float en spécifiant float, double, ou long double à std::uniform_real_distribution< T >. Notez cependant que si l’argument n’est pas l’un d’entre eux, cela donne un comportement indéfini. L’exemple suivant génère des nombres à virgule float de précision unique:

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

using std::cout;
using std::endl;
using std::setprecision;

constexpr int FLOAT_MIN = 10;
constexpr int FLOAT_MAX = 100;

int main() {
  std::random_device rd;
  std::default_random_engine eng(rd());
  std::uniform_real_distribution<float> distr(FLOAT_MIN, FLOAT_MAX);

  for (int n = 0; n < 5; ++n) {
    cout << setprecision(10) << distr(eng) << "\n";
  }

  return EXIT_SUCCESS;
}

Utiliser la fonction rand pour générer un float aléatoire

La fonction random provient de la bibliothèque C et n’est pas recommandée si la qualité randomness est requise. Cette fonction génère un entier pseudo-aléatoire entre 0 et RAND_MAX (tous deux inclus). Puisque la valeur de RAND_MAX dépend de l’implémentation et que la valeur minimale garantie est seulement de 32767, les nombres générés par rand ont un caractère aléatoire contraint. Notez que cette fonction devrait être ensemencée avec std::srand (de préférence en passant l’argument du temps courant), et alors nous pouvons générer des valeurs aléatoires en virgule float avec une arithmétique un peu lourde.

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

using std::cout;
using std::endl;
using std::setprecision;

constexpr int FLOAT_MIN = 10;
constexpr int FLOAT_MAX = 100;

int main() {
  std::random_device rd;
  std::default_random_engine eng(rd());
  std::uniform_real_distribution<float> distr(FLOAT_MIN, FLOAT_MAX);

  for (int n = 0; n < 5; ++n) {
    cout << setprecision(10) << distr(eng) << "\n";
  }
  cout << endl;

  std::srand(std::time(nullptr));
  for (int i = 0; i < 5; i++)
    cout << setprecision(10)
         << FLOAT_MIN +
                (float)(rand()) / ((float)(RAND_MAX / (FLOAT_MAX - FLOAT_MIN)))
         << endl;
  return EXIT_SUCCESS;
}
Auteur: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Article connexe - C++ Float