FAQ CConsultez toutes les FAQ

Nombre d'auteurs : 27, nombre de questions : 175, dernière mise à jour : 17 décembre 2010  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.


SommaireDivers bisLes nombres aléatoires (4)
précédent sommaire suivant
 

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é nul 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 :
srand((unsigned)time(NULL));
rand() et srand() sont déclarées dans stdlib.h. time est déclarée dans time.h.

Mis à jour le 2 février 2003 LFE

Comment obtenir la date et l'heure courante ?

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 :
1
2
3
4
5
6
7
int i; 
  
for(i = 0; i < 10; i++) 
{ 
    srand((unsigned)time(NULL)); 
    printf("tirage : %d\n", rand()); 
}
Affiche plusieurs fois le même nombre lorsqu'elle est exécutée dans la même seconde. Pour avoir un fonctionnement correct, il faut utiliser :

Code C :
1
2
3
4
5
6
int i; 
  
srand((unsigned)time(NULL)); 
  
for(i = 0; i < 10; i++) 
    printf("tirage : %d\n", rand());

Mis à jour le 11 septembre 2006 gl

Il suffit d'écrire une fonction linéaire qui permet de passer de l'intervalle [0, RAND_MAX] à [0, x]. Par exemple :

Code c :
1
2
3
4
double rand_x(double x) 
{ 
    return rand() * (x / RAND_MAX); 
}
Bien entendu, plus x est grand, plus il y aura des nombres qui ne seront jamais retournés. Dans des applications simples, x n'est jamais aussi grand (généralement 1 tout au plus !) alors que RAND_MAX vaut au minimum (cela est imposé par la norme) 32767. Si on devait vraiment générer aléatoirement un nombre x nettement grand devant 1, on pourra toujours générer dans un premier temps la partie entière puis après seulement générer la partie fractionnaire…

Mis à jour le 15 juin 2009 Melem

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 :
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; 
}

Mis à jour le 1er février 2003 gl Jean-Marc.Bourguet

Les nombres aléatoires en C et en C++

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 ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les 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 © 2014 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.

 
 
 
 
Partenaires

PlanetHoster
Ikoula