Discussion: rand() et RAND_MAX

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2013
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2013
    Messages : 26
    Points : 15
    Points
    15

    Par défaut rand() et RAND_MAX

    Bonjour,

    Dans le cadre d'un exercice sur une fonction random, je dois pouvoir faire un tableau dynamique sur une plage définie par l'utilisateur..
    Tout va bien quand celui ci ne choisi pas une plage qui dépasse 32767, qui est donc défini par RAND_MAX.

    J'ai beau lire tout ce que je trouve sur cette fameuse fonction rand(),j'ai bien compris comment définir une plage, incluse ou pas, mais je ne comprend pas comment dépasser la valeur de RAND_MAX??


    Est que l'on pourrait m'expliquer comment faire pour que ma fonction rand dépasse cette fameuse limite et me sorte des nombres qui sont compris dans mon intervalle svp??


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    int main(int argc, char *argv[])
    {
    	// =======================================================================================================
    	// VARIABLE(S) LOCALE
    	// =======================================================================================================
    	long int i, dTailleTab;
    	long int j = 0;
    	long int k = 0;
    	long int *tTabRandom = NULL;
    	long int dNbrRand1, dNbrRand2;
    	long int dNbrTemp;
     
     
     
    	// =======================================================================================================
    	// CODE MAIN
    	// =======================================================================================================
    	printf("Nombre de pistes : ");
    	scanf("%d", &dTailleTab);
     
    	// -------------------------------------------------------------------------------------------------------	
    	// Ajout d'un element aléatoire a la fonction random, via la fonction time() de la librairie time.h
    	// Sinon la fonction random "choisi" tjrs les même résultats
    	srand(time(NULL));
     
    	// -------------------------------------------------------------------------------------------------------	
    	// Création du tableau d'index et initialisation
    	tTabRandom = malloc(dTailleTab * sizeof(long int));
     
    	for (i = 0; i < dTailleTab; i++)
    	{
    		tTabRandom[i] = 1 + i;
    	}
     
     
     
    	// -------------------------------------------------------------------------------------------------------	
    	// Boucle de randomization du tableau
    	for (i = 0; i < dTailleTab; i++)
    	{
    		// -------------------------------------------------------------------------------------------------------	
    		// La fonction random retourne deux  nombre compris dans la taille du tableau tTabIndex,
    		// et vérifie que les deux chiffres sont toujours différent
    		do
    		{
    			dNbrRand1 = (rand() % (dTailleTab));
    			dNbrRand2 = (rand() % (dTailleTab));
    			//printf("%d. dNbrRand1 = %d | dNbrRand2 = %d\n", i, dNbrRand1, dNbrRand2);
    				if (dNbrRand1 == dNbrRand2)
    				{
    					j++;
    					//printf("\t%d WARNING!! dNbrRand1 = %d | dNbrRand2 = %d\n", i, dNbrRand1, dNbrRand2);
    				}
    				if (dNbrRand1 >= 32767 || dNbrRand2 >= 32767)
    				{
    					//printf("\t%d dNbrRand1 = %d | dNbrRand2 = %d\n", i, dNbrRand1, dNbrRand2);
    					k++;
    				}
    		}
    		while (dNbrRand1 == dNbrRand2);
     
    		// -------------------------------------------------------------------------------------------------------	
    		// Utilisation des nombres retourné par la fonction rand() pour intervertir les nombres aux index 
    		// correspondant dans ptTabRandom 
    		dNbrTemp = tTabRandom[dNbrRand2];
    		tTabRandom[dNbrRand2] = tTabRandom[dNbrRand1];
    		tTabRandom[dNbrRand1] = dNbrTemp;
    	}
     
    	printf("\n");
     
    	for (i = 0; i < dTailleTab; i++)
    	{
    			printf(" %d |", tTabRandom[i]);
    	}
     
    	printf("\n");
    	printf("WARNING = %d\n", j);
    	printf("+ 32767 = %d\n", j);
    	printf("\n");
    	free(tTabRandom);
    	return 0;
    }
    Les printf un peu partout sont la pour m'aider a voir ce qu'il se passe dans mon code..

    Merci d'avance

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 836
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 4 836
    Points : 15 731
    Points
    15 731

    Par défaut

    la fonction rand() génère RAND_MAX (+1?) valeurs distinctes.
    Tu ne peux pas générer plus de valeurs distinctes sans l'invoquer plusieurs fois.
    Tu peux envisager d'utiliser une fonction intermédiaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    long ultra_rand() { return long(rand()) + long(RAND_MAX)*long(rand()); }
    Il est important d'utiliser rand() deux fois, et pas de faire simplement (long(RAND_MAX)+1) * rand().
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2013
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mars 2013
    Messages : 26
    Points : 15
    Points
    15

    Par défaut

    Ma question étant de savoir comment dépasser la limite de MAX_RAND quand je veux utiliser le nbr renvoyer par rand() pour aller chercher un l'index d'un tableau de + de 32767??

    J'avoue ne pas comprendre ta réponse.. et si elle s'applique a ma question

  4. #4
    Membre habitué Avatar de Matthieu76
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2013
    Messages
    171
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2013
    Messages : 171
    Points : 152
    Points
    152

    Par défaut

    Tu peux essayer un truc du genre rand() * rand() mais je ne pense pas que tout tes index ait la même probabilité de sortir.

    Le mieux c'est d’affecter un rand() à chaque ligne de ton tableau et de prendre la plus petite ou la plus grande valeur.

    Ou sinon mieux, tire 2 nombres en 0 et RAND_MAX puis tu utilise la formule suivante : rand1 * RAND_MAX + rand2 et tu obtiens un nouveau nombre en 0 et RAND_MAX².

  5. #5
    Membre émérite
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    495
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 495
    Points : 2 510
    Points
    2 510

    Par défaut

    Citation Envoyé par Matthieu76 Voir le message
    Ou sinon mieux, tire 2 nombres en 0 et RAND_MAX puis tu utilise la formule suivante : rand1 * RAND_MAX + rand2 et tu obtiens un nouveau nombre en 0 et RAND_MAX².
    C'est la solution indiquée par ternel.
    Plus exactement pour avoir un nombre compris entre 0 et nMax inclus avec N>RAND_MAX on peut écrire la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    unsigned long aleat( unsigned long nMax ) {
       unsigned long long x = rand() * (RAND_MAX+1uLL) + rand();
       x = x * (nMax+1uLL) / ((unsigned long)(RAND_MAX+1)*(RAND_MAX+1));
       return (unsigned long)x;
    }
    Fonctionne si nMax+1 est ≤ à (RAND_MAX+1)² c-à-d 1.07 milliard

Discussions similaires

  1. rand() et RAND_MAX
    Par endreillie dans le forum Débuter
    Réponses: 3
    Dernier message: 21/10/2010, 14h44
  2. Comportement étrange de rand() et RAND_MAX
    Par souviron34 dans le forum C
    Réponses: 11
    Dernier message: 24/04/2007, 11h42
  3. Pb de rand() qui tourne en boucle
    Par MadChris dans le forum MFC
    Réponses: 3
    Dernier message: 26/06/2004, 16h24
  4. Probleme de tirage avec rand ?
    Par sunshine33 dans le forum MFC
    Réponses: 5
    Dernier message: 14/01/2004, 15h57
  5. rand
    Par drKzs dans le forum C
    Réponses: 6
    Dernier message: 21/09/2003, 16h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo