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 :

srand me donne des nombres croissants


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Par défaut srand me donne des nombres croissants
    Bonjour à tous!
    J'ai un petit problème dont je ne comprend pas le "fonctionnement":
    Je me trouve présentement avec un classe Devinette qui réalise le simple jeux trouve le nombre.. trop petit... trop grand, je génère donc un chiffre aléatoire avec une classe Randomize, or il me génère bien des nombres aléatoire mais dans l'ordre croissant... Voici mes classes:
    Devinette
    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
     
    class Devinette
    {
    public :
        static enum {TROP_GRAND = 2, TROP_PETIT = -1, SUCCES = 1, AUCUN_TEST = 0};
        static enum {VALEUR_MINIMALE = 1, VALEUR_MAXIMALE = 100000};
        int iNombreAleatoire; 
    private :
        static Randomize GestionnaireAleatoire;
        unsigned int iNombreEssai;
        bool bReussite;
     
     
     
    public :
        Devinette();
        static bool EstNombreValide(int _nombre);
        int Essayer(int _nombre) ;
        bool EstReussi() const;
        unsigned int GetNombreEssais() const ;
     
    };
    Dans mon Devinette.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Randomize Devinette::GestionnaireAleatoire;
    Randomize
    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
     
    class Randomize
    {
     
    public:
     
        Randomize()
        {
           srand(static_cast<unsigned int>(time(0)));
        }
     
        static int GetRandomNumber(const int _max, const int _min)
        {
            return ((rand() % (_max - _min + 1)) + _min);
        }
    };
    Ayant passer pas mal de temps sur java, j'ai oublié un peu mes classiques de C++ .
    Ce que je ne comprend pas c'est pourquoi... Je ne pense pas qu'il s'agit d'un problème énorme... mais je ne vois pas le problème!
    Merci

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Tu devrais utiliser la formule passant par des floats, plutôt qu'un modulo.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    il ne faut pas changer tout le temps le int en paramètre sinon tu réinitialises a chaque fois le générateur.

    The srand() function sets its argument as the seed for a new sequence of pseudo-random integers to be returned by rand(). These sequences are repeatable by calling srand() with the same seed value.
    http://linux.die.net/man/3/srand

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Citation Envoyé par jabbounet Voir le message
    il ne faut pas changer tout le temps le int en paramètre sinon tu reinitiliser a chaque fois le générateur.
    Sauf qu'il s'agit d'une variable statique: Il n'est initialisé qu'une seule fois, ce qui est correct.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    Il y a une discussion sur srand assez intéressante.

  6. #6
    Invité
    Invité(e)
    Par défaut
    A vue de nez, tu dois réinstancier ton générateur à chaque appel... (c'est la seule explication pour tes nombres croissants) Pour en etre sur, essaye de remplacer, dans le constructeur de randomize, time(0) par une valeur constante, et regarde si ton programme te renvoie toujours cette valeur...

    Si la valeur est toujours la même c'est forcément que GetRandomNumber() n'est pas appelée...

    Tu l'appelles comment GetRandomNumber()?

    Aussi, je ne suis pas certain de comprendre le static int devant sa déclaration... Ca en fait une fonction statique, je crois, mais sur une classe instanciée, dont on définit dans une autre classe une instance statique...

    Ca sent un peu le soufre, quoi...

    J'ai l'impression qu'un appel à srand() au début de l'application, puis des appels à rand(), sans cette classe Randomize qui semble être la cause de tous tes malheurs (et qui n'apporte rien) te mènerait assez loin.

    Francois

  7. #7
    Membre Expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Je confirme un utilisation incorrecte de la classe Randomize peux donner de mauvais résultats.

    Quand je recrée a chaque fois Randomize, j'ai un résultat constant (probablement due à la granularité de la fonction time).

    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
     
    #include <iostream>
     
    class Randomize
    {
     
    public:
     
        Randomize()
        {
           srand(static_cast<unsigned int>(time(0)));
        }
     
      static int GetRandomNumber(const int _max, const int _min)
      {
        return ((rand() % (_max - _min + 1)) + _min);
      }
    };
     
     
    int getBadRand() {
      Randomize *r = new Randomize();
      //  sleep(1);
      int random = r ->  GetRandomNumber(1000000,0);
      delete r;
      return random;
    }
     
     
    int main(int argc,char* *argv)
    {
      Randomize *r = new Randomize();
     
      std::cout << "Correct random generation :"  << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl
                << r ->  GetRandomNumber(1000000,0) << std::endl;
      delete r;
     
      std::cout << "Bad random generation :"  << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl
                << getBadRand() << std::endl;
     
      return 0;
    }
    g++ randomtest.cpp -o randomtest && ./randomtest
    Correct random generation :
    215328
    170112
    138454
    184037
    39074
    346258
    110469
    271663
    856304
    Bad random generation :
    856304
    856304
    856304
    856304
    856304
    856304
    856304
    856304
    856304

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    En effet, pour ce genre de choses, il vaut mieux rendre la classe entièrement statique:
    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
    #include <iostream>
     
    class Randomize
    { 
    private:
        Randomize()
        {
           srand(static_cast<unsigned int>(time(0)));
        }
     
        static Randomize instance;
    public:
      static int GetRandomNumber(const int _max, const int _min)
      {
        //je ne sais plus si c'est nécessaire,
        //mais je veux être sûr que l'instance soit créée.
        (void)instance;
        //Retourne une nouvelle valeur.
        //La version float serait préférable.
        return ((rand() % (_max - _min + 1)) + _min);
      }
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Randomize Randomize::instance;
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    En effet, pour ce genre de choses, il vaut mieux rendre la classe entièrement statique:
    Oui, mais alors, il va falloir qu'on m'explique l'intéret de la classe, par rapport à un bête srand() au début du programme et une fonction "libre" GetRand(min,max) qu'on appelle quand on a besoin...

    Une classe entièrement statique, sans données membres, et n'ayant qu'une fonction, j'avoue que je ne vois pas l'utilité.

    Francois

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Le seul avantage est que srand() est automatiquement appelé, ce qui en vaut pas forcément grand-chose.

    Les vraies classes Random sont supposées maintenir leur propre statut, ce qui permet d'avoir des données reproductibles sans déranger les autres parties du programme qui ont besoin de valeurs pseudo-aléatoires (et potentiellement reproductibles).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Ne jamais utilisé le modulo avec le résultat de rand(). (y'a bien une entrée de la faq là dessus non?)

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

Discussions similaires

  1. donne le nombre des mois entre deux dates
    Par Sokol dans le forum SAS Base
    Réponses: 1
    Dernier message: 09/11/2009, 12h55
  2. [Batch] Trier des nombres ordre croissant dans fichier texte
    Par AZzjeioafh dans le forum Scripts/Batch
    Réponses: 20
    Dernier message: 01/11/2009, 10h22
  3. algo qui affiche par ordre croissant des nombres
    Par jeremdu69300 dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 18/09/2008, 23h16
  4. Réponses: 1
    Dernier message: 09/11/2007, 18h40
  5. Probleme de tri croissant pour des nombres
    Par sebastien_oasis dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 11/08/2007, 10h14

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