IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Constation etrange sur rand() !


Sujet :

C

  1. #1
    Membre à l'essai
    Inscrit en
    Février 2010
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 14
    Points : 16
    Points
    16
    Par défaut Constation etrange sur rand() !
    Bonjour,

    Encore une fois une petite des petites pas très importantes :

    Pour tenter de comprendre la fonction rand je lance la programme très basique suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
     
    int main()
    {
        srand((unsigned)time(NULL));
     
        printf("%d",rand());
        return 0;
    }
    Je m'aperçois que les nombres renvoyés sont proches et de plus en plus grands, en gros ils augmentent toujours de la même chose (2308 puis 2330,2378..), Je suppose que le premier usage de rand() est directement lié au temps du genre : (moment de l'execution du time(NULL) %rand_max, j'ai bon ? La première utilisation de rand est très prédictible alors.



    Au passage y a t'il une raison (autre qu'historique) pour que rand_max ne soit pas égal à la taille maximal d'un unsigned int ?

    Passons au programme suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
     
    int main()
    {
        srand((unsigned)time(NULL));
     
        printf("%d %d",rand(),rand());
        return 0;
    }
    Je me dis que la progression lente va être sur le premier nombre renvoyé mais elle l'est sur le second ! (genre 1520 2304 puis 16823 2316 ...). printf lit il les arguments de droite à gauche ?

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 984
    Points
    30 984
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par erik2003 Voir le message
    Pour tenter de comprendre la fonction rand je lance la programme très basique suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
     
    int main()
    {
        srand((unsigned)time(NULL));
     
        printf("%d",rand());
        return 0;
    }
    Je m'aperçois que les nombres renvoyés sont proches et de plus en plus grands, en gros ils augmentent toujours de la même chose (2308 puis 2330,2378..), Je suppose que le premier usage de rand() est directement lié au temps du genre : (moment de l'execution du time(NULL) %rand_max, j'ai bon ? La première utilisation de rand est très prédictible alors.
    Bonjour
    Oui à peu près. Je présume que tu es sur une machine Linux laquelle décompte son temps machine en secondes. Donc si tu exécutes ton code plusieurs fois dans la même seconde (ce qui est très facile), le srand() sera initialisé avec la même valeur ce qui te donnera un rand() identique à chaque cas.

    Perso je rajoute un getpid() dans le srand() => srand((unsigned)time(NULL) ^ getpid());.

    Mais si tu veux vraiment examiner la gestion de l'aléatoire, il faut alors que ce soit ton programme qui te génère plusieurs nombres et non toi qui l'appelle plusieurs fois. Un programme qui ne fait qu'une seule initialisation mais qui, ensuite, génère et affiche des nombres dans une boucle...

    Citation Envoyé par erik2003 Voir le message
    Au passage y a t'il une raison (autre qu'historique) pour que rand_max ne soit pas égal à la taille maximal d'un unsigned int ?
    Je crois qu'il est à la taille maximale d'un signed short. Peut-être parce qu'à l'époque le int valait généralement un short...

    Citation Envoyé par erik2003 Voir le message
    printf lit il les arguments de droite à gauche ?
    Je crois qu'il y a un truc avec printf et notemment dans ce genre d'instruction: printf("%d %d\n", i++, i++) qui ne garantit pas l'ordre de l'affichage donc ça rejoint ta question. Mais en quoi ça devrait te poser un problème ? T'as qu'à stocker les deux rand() dans deux variables a et b que tu affiches ensuite...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre à l'essai
    Inscrit en
    Février 2010
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 14
    Points : 16
    Points
    16
    Par défaut
    Merci

  4. #4
    Membre éclairé
    Inscrit en
    Juillet 2012
    Messages
    231
    Détails du profil
    Informations forums :
    Inscription : Juillet 2012
    Messages : 231
    Points : 870
    Points
    870
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Je crois qu'il y a un truc avec printf
    Ce n'est pas un truc avec printf en particulier, c'est juste qu'en C l'ordre d'évaluation des arguments d'une fonction est définie par l'implémentation (chaque compilo' peut faire son choix mais il doit le documenter (pour GCC, c'est ici)).
    Par exemple, le code suivant:
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
     
    int f(void)
    {
        static int i = 0;
        return ++i;
    }
     
    int main(int argc, char *argv[])
    {
        printf("%d %d\n", f(), f());
        return 0;
    }

    avec GCC il affichera
    Et avec clang on aura:
    Citation Envoyé par Sve@r Voir le message
    et notemment dans ce genre d'instruction: printf("%d %d\n", i++, i++)
    Ça c'est encore pire, cette fois on a un comportement indéfini car tu modifies 2 fois la même variable dans un point séquence. Un GCC bien configuré devrait même te donner un warning sur celui-là.

  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    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 : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Pour le problème des valeurs de rand().

    Il faut comprendre le principe derrière.
    la génération de nombre pseudo-aléatoire, comme rand le fait, est basée sur des suites difficiles à déterminer.
    srand permet de spécifier la "seed", qui est l'identifiant de la suite à utiliser, et rand se contente de parcourir cette suite.

    time(null) donnant une valeur relativement différente à chaque lancement de programme (son heure de lancement), et les suites étant différente, srand(time(null)) est un moyen de ne pas choisir de manière déterministe la suite à utiliser.

    Comme Sve@r l'a dit, ton programme est très rapide, et affiche le premier nombre de cette suite.
    Tu n'utilise pas du tout le hasard apparent en appelant de nombreuses fois 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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/03/2012, 10h38
  2. [XL-2002] Problème etrange sur excel! #valeur!
    Par dany_dane dans le forum Excel
    Réponses: 4
    Dernier message: 11/01/2010, 23h07
  3. Arrêt étrange sur un vieux portable
    Par Eusebius dans le forum Matériel
    Réponses: 13
    Dernier message: 06/11/2006, 20h32
  4. Erreur etrange sur une requete
    Par mael94420 dans le forum ASP
    Réponses: 3
    Dernier message: 12/03/2006, 22h25
  5. champ etrange sur DB2
    Par rodolphedj dans le forum ASP
    Réponses: 4
    Dernier message: 19/10/2004, 09h05

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