Un jour, mon professeur m'a appris à utiliser randomize()
y random()
pour générer des nombres pseudo-aléatoires en C++ Builder. Maintenant je préfère travailler dans VS 2012, mais quand j'ai essayé d'utiliser ces fonctions, il m'a dit que l'identifiant n'était pas trouvé, même quand j'ai ajouté #include <stdlib.h>
. Après quelques recherches sur Google, j'ai découvert qu'il existe également des rand()
y srand()
fonctions. Quelle est la différence entre les deux et quelle est la meilleure solution ?
Réponses
Trop de publicités?randomize()
y random()
ne font pas partie de la bibliothèque standard. Votre professeur a peut-être écrit des fonctions portant ces noms pour les utiliser dans votre classe, ou bien vous voulez vraiment dire random()
y srandom()
qui font partie de POSIX et ne sont pas disponibles sous Windows. rand()
y srand()
font partie de la bibliothèque standard et seront fournis par toute implémentation de C++ conforme à la norme.
Vous devez éviter rand()
y srand()
et utiliser la nouvelle norme C++11 <random>
bibliothèque. <random>
a été ajoutée dans le cadre de la norme C++11 (et VS2012 la fournit).
Vidéo expliquant pourquoi : rand()
Considéré comme nuisible
-
rand()
est généralement un pRNG de faible qualité et ne convient pas aux applications qui nécessitent un niveau raisonnable d'imprévisibilité.<random>
offre une variété de moteurs aux caractéristiques différentes, adaptés à de nombreux cas d'utilisation. -
Convertir les résultats de
rand()
en un nombre directement utilisable repose généralement sur un code difficile à lire et facile à confondre, alors que l'utilisation de<random>
Les distributions sont faciles et produisent un code lisible. -
Les méthodes les plus courantes pour générer des valeurs dans une distribution donnée sont les suivantes
rand()
diminuent encore la qualité des données générées.%
biaise généralement les données et la division en virgule flottante produit toujours des distributions non uniformes.<random>
sont de meilleure qualité et plus lisibles. -
rand()
s'appuie sur une ressource mondiale cachée. Cela entraîne, entre autres, les problèmes suivantsrand()
de ne pas être à l'abri d'un fil. Certaines implémentations offrent des garanties de sécurité, mais il ne s'agit pas d'une norme obligatoire. Les moteurs fournis par<random>
encapsulent l'état de pRNG sous forme d'objets avec une sémantique de valeur, ce qui permet un contrôle flexible de l'état. -
srand()
ne permet qu'une gamme limitée de semences. Les moteurs en<random>
peuvent être initialisés à l'aide de séquences de semences qui permettent d'obtenir le plus grand nombre possible de données de semences.seed_seq
met également en œuvre un échauffement commun du pRNG.
exemple d'utilisation <random>
:
#include <iostream>
#include <random>
int main() {
// create source of randomness, and initialize it with non-deterministic seed
std::random_device r;
std::seed_seq seed{r(), r(), r(), r(), r(), r(), r(), r()};
std::mt19937 eng{seed};
// a distribution that takes randomness and produces values in specified range
std::uniform_int_distribution<> dist(1,6);
for (int i=0; i<100; ++i) {
std::cout << dist(eng) << '\n';
}
}
Bien qu'il y ait (évidemment, ci-dessus) des personnes qui affirmeront avec une ferveur religieuse que rand() est mauvais et aléatoire() ne l'est pas, il s'avère que votre kilométrage peut varier. Voici la réponse de gcc à la question "Quelle est la différence...", telle qu'elle est fournie par la version gcc de stdlib.h (c'est nous qui soulignons) :
/* These are the functions that actually do things. The `random', `srandom',
`initstate' and `setstate' functions are those from BSD Unices.
The `rand' and `srand' functions are required by the ANSI standard.
**We provide both interfaces to the same random number generator.** */
/* Return a random long integer between 0 and RAND_MAX inclusive. */
Fonctions rand()
y random()
sont soit définies par POSIX depuis au moins POSIX.1-2001 (et randomize()
n'est pas normalisé).
Sur les plus anciens rand()
et sur les implémentations actuelles sur différents systèmes, les bits de poids faible sont beaucoup moins aléatoires que les bits de poids fort.
Lorsqu'ils sont disponibles, random()
ne souffre pas de ce problème.
En plus, la version moderne de rand()
utilisent le même générateur de nombres aléatoires que random()
. Ainsi rand()
peut être correcte, mais elle n'est pas garantie.
Il faut donc toujours utiliser random()
au lieu de rand()
. Si random()
n'est pas disponible sur votre système d'exploitation, demandez aux développeurs du système d'exploitation de fournir une implémentation de l'API des normes plus récentes (la norme 2001 est maintenant suffisamment ancienne pour que n'importe quel système la fournisse).
srand()
est l'implémentation de la bibliothèque standard C pour alimenter le générateur de nombres (pseudo) aléatoires. rand()
est le générateur de nombres (pseudo) aléatoires de la bibliothèque standard C.
C++ a mis en œuvre un nouveau générateur de nombres aléatoires (pseudo) dans le module <random>
qui dispose d'un grand nombre de moteurs différents à utiliser : http://en.cppreference.com/w/cpp/numeric/random
Il semble que vous utilisiez des fonctions de type C, bien que votre question porte la mention C++. De plus, il est possible d'utiliser des fonctions de type C, même si votre question est intitulée C++, stdlib.h
est un fichier d'en-tête de la bibliothèque standard C. Il n'y a pas de telles fonctions random()
y randomize()
dans la bibliothèque standard C. La bibliothèque standard C comprend rand()
y srand()
.
Si vous utilisiez random()
ou quelque chose comme ça à travers stdlib.h
Il doit s'agir d'une extension de bibliothèque non standard dans le compilateur Borland.
Donc, si vous voulez vous en tenir à des fonctions standard de style C, ce serait, encore une fois, le cas, rand()
y srand()
. Mais si vous écrivez en C++, vous pourriez avoir de meilleures options (et plus appropriées) dans la bibliothèque standard de C++.
- Réponses précédentes
- Plus de réponses