FAQ CConsultez toutes les FAQ
Nombre d'auteurs : 35, nombre de questions : 194, dernière mise à jour : 18 février 2018 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de www.developpez.com et de l'expérience personnelle des auteurs.
Je tiens à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez devenir rédacteur, lisez ceci .
Sur ce, je vous souhaite une bonne lecture.
La fonction rand() renvoie des nombres pseudo-aléatoires qui sont les termes d'une suite pseudo-aléatoire. Les termes de cette suite sont des nombres compris entre 0 et RAND_MAX. Si cette suite est toujours la même, alors ces nombres seront aussi toujours les mêmes. Il faut donc utiliser une suite différente à chaque exécution pour avoir des résultats assez satisfaisants. C'est là qu'intervient la fonction srand(). Cette fonction, qui permet d'initialiser le générateur de nombres aléatoires avec le nombre passé en argument appelé graine (attention, il n'est spécifié nulle part que ce nombre sera le premier terme de la suite…), doit toujours être appelée en début de tout programme utilisant les nombres aléatoires. Comme notre but est d'avoir une suite différente à chaque exécution, le problème revient donc en fait à changer de graine à chaque exécution. Une méthode largement admise comme solution est d'utiliser le temps pour graine. Ainsi, tout programme utilisant les nombres aléatoires doit toujours commencer par :
Code c : | Sélectionner tout |
srand((unsigned)time(NULL));
Vous appelez certainement srand() plus d'une fois dans le programme. En effet, srand() permet d'initialiser le générateur de nombres pseudo-aléatoires. Toutefois, si l'unité de temps dans la fonction time() est la seconde (ce qui est généralement le cas) et que srand(time(NULL)) est appelé plus d'une fois lors de la même seconde, le générateur est réinitialisé à chaque fois avec la même valeur et génèrera la même séquence de nombres. Ainsi :
Code C : | Sélectionner tout |
1 2 3 4 5 6 7 | int i; for(i = 0; i < 10; i++) { srand((unsigned)time(NULL)); printf("tirage : %d\n", rand()); } |
Code C : | Sélectionner tout |
1 2 3 4 5 6 | int i; srand((unsigned)time(NULL)); for(i = 0; i < 10; i++) printf("tirage : %d\n", rand()); |
Il suffit d'écrire une fonction linéaire qui permet de passer de l'intervalle [0, RAND_MAX] à [0, x]. Par exemple :
Code c : | Sélectionner tout |
1 2 3 4 | double rand_x(double x) { return rand() * (x / RAND_MAX); } |
La méthode la plus simple pour obtenir un nombre « aléatoire » entre 0 (inclus) et N (inclus) consiste à utiliser l'opérateur modulo : randvalue = rand() % (N + 1);. Cette méthode permet, certes, d'obtenir un nombre toujours compris entre 0 et N, mais la suite de nombres obtenus n'est pas forcément très « aléatoire » car :
- elle utilise les bits de poids faible des nombres retournés par la fonction rand() or de nombreux générateurs de nombres aléatoires simples génèrent des nombres avec des bits de poids faible non aléatoires ;
- elle introduit un biais lorsque RAND_MAX n'est pas un multiple de N + 1.
La méthode suivante permet d'éliminer les différents biais sans favoriser les bits de poids faible :
Code C : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <stdlib.h> int rand_n(int n) { int partSize = 1 + (n == RAND_MAX ? 0 : (RAND_MAX - n) / (n + 1)); int maxUsefull = partSize * n + (partSize - 1); int draw; do { draw = rand(); } while (draw > maxUsefull); return draw / partSize; } |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.