web-dev-qa-db-fra.com

Quelle différence entre les fonctions Rand () et random ()?

Une fois, mon professeur m'a appris à utiliser la fonction randomize() et random() pour générer des nombres pseudo-aléatoires dans C++ Builder. Maintenant, je préfère travailler dans VS 2012, mais quand j'ai essayé d'utiliser ces fonctions là, il est dit "identifiant non trouvé", même lorsque j'ai ajouté #include <stdlib.h>. Après un certain temps de recherche sur Google, j'ai constaté qu'il existe également des fonctions Rand() et srand(). Quelle est la différence entre eux et lequel est-il préférable d'utiliser?

19
Sunrise

randomize() et random() ne font pas partie de la bibliothèque standard. Peut-être que votre professeur a écrit des fonctions avec ces noms pour les utiliser dans votre classe, ou peut-être voulez-vous vraiment dire random() et srandom() qui font partie de POSIX et ne sont pas disponibles sur Windows. Rand() et srand() font partie de la bibliothèque standard et seront fournis par toute implémentation conforme de C++.


Vous devez éviter Rand() et srand() et utiliser la nouvelle bibliothèque C++ 11 <random>. <random> A été ajouté dans le cadre de la norme C++ 11 (et VS2012 le fournit).

Vidéo expliquant pourquoi: Rand() considérée comme nuisible

  • Rand() est généralement un pRNG de faible qualité et ne convient pas aux applications qui ont besoin d'un niveau raisonnable d'imprévisibilité. <random> Fournit une variété de moteurs avec des caractéristiques différentes adaptées à de nombreux cas d'utilisation différents.

  • La conversion des résultats de Rand() en un nombre que vous pouvez utiliser directement repose généralement sur du code difficile à lire et facile à se tromper, tandis que l'utilisation des distributions <random> Est facile et produit du code lisible.

  • Les méthodes courantes de génération de valeurs dans une distribution donnée à l'aide de 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. Les distributions <random> Sont de meilleure qualité et plus lisibles.

  • Rand() repose sur une ressource globale cachée. Entre autres problèmes, cela empêche Rand() d'être thread-safe. Certaines implémentations garantissent la sécurité des threads, mais ce n'est pas une norme requise. Les moteurs fournis par <random> Encapsulent l'état pRNG en tant qu'objets avec une sémantique de valeur, permettant un contrôle flexible de l'état.

  • srand() n'autorise qu'une gamme limitée de graines. Les moteurs dans <random> Peuvent être initialisés en utilisant des séquences de graines qui permettent le maximum de données de graines possibles. seed_seq Implémente également un échauffement pRNG commun.


exemple d'utilisation de <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';
  }
}
32
bames53

Bien qu'il y ait (évidemment, ci-dessus) des gens qui affirmeront avec 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 que fournie par la version gcc de stdlib.h (non souligné dans l'original):

/ * Ce sont les fonctions qui font réellement les choses. Les fonctions random', Srandom ', initstate' and Setstate' sont celles des BSD Unices. Les fonctions Rand' and Srand sont requises par la norme ANSI. Nous fournissons les deux interfaces au même générateur de nombres aléatoires.// Retourne un entier long aléatoire entre 0 et Rand_MAX inclus. * /

5
Atlant

Il semble que vous utilisiez des fonctions de style C, même si votre question est intitulée C++. De plus, stdlib.h Est un fichier d'en-tête de la bibliothèque standard C. Il n'y a pas de telles fonctions sont random() et randomize() dans la bibliothèque standard C. La bibliothèque standard C a Rand() et srand().

Si vous utilisiez random() ou quelque chose du genre via stdlib.h, Il devait s'agir d'une extension de bibliothèque non standard dans le package du compilateur Borland.

Donc, si vous voulez vous en tenir aux fonctions standard de style C, ce serait, encore une fois, Rand() et srand(). Mais si vous écrivez en C++, vous pourriez avoir de meilleures options (et plus appropriées) dans la bibliothèque standard C++.

4
AnT

Les fonctions Rand() et random() sont soit définies par POSIX depuis au moins POSIX.1-2001 (et randomize() n'est pas standardisée).

Sur les anciennes implémentations 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'elle est disponible, random() ne souffre pas de ce problème.

De plus, la version moderne de Rand() utilise le même générateur de nombres aléatoires que random(). Donc Rand() peut être correct, mais ce n'est pas garanti.

Donc, utilisez toujours 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 API de normes plus récentes (la norme 2001 est maintenant suffisamment ancienne pour que tout système puisse la fournir).

2
Jérôme Pouiller

srand() est l'implémentation de la bibliothèque C Standard pour amorcer le générateur (pseudo) de nombres aléatoires. Rand() est le (pseudo) générateur de nombres aléatoires dans la bibliothèque standard C.

C++ a implémenté un nouveau (pseudo) générateur de nombres aléatoires dans le <random> fichier d'en-tête, qui a une variété de moteurs différents à utiliser: http://en.cppreference.com/w/cpp/numeric/random

2
Zac Howland

Je ne connais pas randomize() et random() mais ils ne font pas partie de la bibliothèque standard. Vous devez éviter d'utiliser Rand() cette vidéo explique pourquoi l'utilisation de Rand () est considérée comme nuisible .

Vous devriez utiliser le en-tête aléatoire introduit dans C++ 11 , voici un exemple utilisant les deux std: : uniform_real_distribution et std :: uniform_int_distribution :

#include <iostream>
#include <random>

int main()
{
    std::random_device rd;

    std::mt19937 e2(rd());

    std::uniform_int_distribution<> dist(1, 6);
    std::uniform_real_distribution<> distReal(1, 6);

    for( int i = 0 ; i < 10; ++i )
    {
       std::cout << dist(e2) << ",";
    }
    std::cout << std::endl ;

    for( int i = 0 ; i < 10; ++i )
    {
       std::cout << distReal(e2) << ",";
    }
    std::cout << std::endl ;

    return 0 ;
}
1
Shafik Yaghmour