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 :

template fonction aléatoire


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Lycéen
    Inscrit en
    Novembre 2009
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2009
    Messages : 67
    Par défaut template fonction aléatoire
    Bonjour,

    je cherche à réaliser une fonction qui genererait un nombre aléatoire entre un minimum et un maximum, j'ai coder ca mais ca me donne une erreur

    invalid operands of types 'int' and 'double' to binary 'operator%'|

    Est ce qu'il faut surcharger l'opérateur % ? Si oui comment faire ?

    Voici le code

    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
    #include<iostream>
    #include<vector>
    #include <ctime>
    #include <cstdlib>
     
    using namespace std;
     
            template<typename T>
        T aleatoire(T minn, T maxx)
        {
            return (minn + (rand () % (maxx-minn+1)));
        }
     
    int main()
    {
        srand(time(0));
        int minimum(5);
        int maximum(10);
        double minimumd(1);
        double maximumd(100);
     
        cout << aleatoire(minimum, maximum) << aleatoire(minimumd, maximumd) << endl;
    }
    Merci d'avance !

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    Je pense que la FAQ pourrait te donner quelques pistes.

  3. #3
    Membre Expert Avatar de Ehonn
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    788
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

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

    Informations forums :
    Inscription : Février 2012
    Messages : 788
    Par défaut
    Si ce n'est pas dans un but pédagogique, tourne toi vers std::random (C++11) ou boost::random.
    Voici un post qui pourrait t'aider :
    http://www.developpez.net/forums/d13...chier-lecture/
    Et voici uniform distribution de la std (tu pourrais t'inspirer de l'interface à défaut de l'utiliser)
    http://www.cplusplus.com/reference/r..._distribution/

  4. #4
    Membre confirmé
    Profil pro
    Lycéen
    Inscrit en
    Novembre 2009
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2009
    Messages : 67
    Par défaut
    Salut Neckara et merci de ta réponse, cependant c'est un lien vers la faq C, et quand je regarde et que j'essaye de l'appliquer à mon code, je ne vois pas l'erreur que je j'ai commise.

    Salut Ehonn, une fois de plus merci, j'essaye ce code pour m'entrainer à mieux comprendre les template ^^, mais je vais quand même voir

    Merci à vous encore.

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    % est le modulo, il n'est défini que pour un opérande de droite entier.

    avec T=double, l'opérande droit n'est plus entier.

    essaie une conversion, ou interdit le double (et le float)

  6. #6
    Membre confirmé
    Profil pro
    Lycéen
    Inscrit en
    Novembre 2009
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2009
    Messages : 67
    Par défaut
    Ah ok !

    Donc dans:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (minn + (rand () % (maxx-minn+1)));
    je dois convertir le resultat de maxx-minn+1 en int ?
    Si oui comment faire ? un cast quelque chose non ? Je me souviens plus ^^

  7. #7
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    caster? par un simple C-cast tel que (int) valeur ou mieux un cast C++, probablement le static_cast<int>(valeur).

    Il y a une autre variante possible
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<typename T>
    T aleatoire(T base, int ecart_max) {
        return base + rand () % (1 + ecart_max);
    }
    Cela dit, tu devrais regarder du côté de boost/C++11 pour la génération propre, efficace et avec une bonne qualité d'aléatoire

  8. #8
    Membre confirmé
    Profil pro
    Lycéen
    Inscrit en
    Novembre 2009
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2009
    Messages : 67
    Par défaut
    Super, là ca marche, j'ai définit une variable double valant 100.24 que j'ai mise en deuxième argument de la fonction, et ca a fonctionné, alors qu'il s'agit d'un double, elle est convertit automatiquement ?

  9. #9
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Sauf que cette solution va tronquer le double, ainsi si ton maximum est 4.5, ton maximum sera en fait 4.

    La FAQ montre un code pour généré un nombre aléatoire entre 0 et X :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    double rand_x(double x)
    {
        return rand() * (x / RAND_MAX);
    }
    Qu'on peut aisément transformer en :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<typename T> T rand_x(T x)
    {
         return rand() * (x / RAND_MAX);
    }
    Ce qui peut donner :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<typename T> T rand_x(T base, T ecart)
    {
         return base + rand() * (ecart / RAND_MAX);
    }
    Est-ce que ceci ne marcherait pas ?

  10. #10
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    oui, parce que tu affectes un double à un int, explicitement.


    maxx-minn était du type T, "T-1" est encore un T, et base%(T) n'est valable que pour T un type entier. (ou pour % redéfini pour le type de base et pour T)

  11. #11
    Membre confirmé
    Profil pro
    Lycéen
    Inscrit en
    Novembre 2009
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2009
    Messages : 67
    Par défaut
    In function 'int main()':|
    22|error: no matching function for call to 'aleatoire(double&, int&)'|
    22|note: candidate is:|
    8|note: template<class T> T aleatoire(T, T)|
    8|note: template argument deduction/substitution failed:|
    22|note: deduced conflicting types for parameter 'T' ('double' and 'int')|

    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
    #include<iostream>
    #include<vector>
    #include <ctime>
    #include <cstdlib>
     
    using namespace std;
     
           template<typename T> T aleatoire(T minn, T maxx)
    {
         return minn + rand() * (minn / RAND_MAX);
    }
     
     
    int main()
    {
        srand(time(0));
        int minimum(5);
        int maximum(10);
        double minimumd(1.54);
        double maximumd(100.24);
     
        cout << aleatoire(minimum, maximum) << " " << aleatoire(minimumd,maximum) << endl;
    }
    Autre chose étrange, quand je remplace le minimumd(valant 1.24) de aleatoire(minimumd,maximum), par minimum(valant 5), la console m'affiche systematiquement le chiffre 5, mais tout le temps (j'ai essayé 40 fois pour voir si c'était pas juste de la chance)

  12. #12
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Pour ton premier message d'erreur, le problème vient juste du fait que le compilateur ne sait pas s'il doit utiliser un int ou un double, il faut donc lui dire explicitement ce qu'on veut :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    aleatoire<int>(5.5, 4);
    aleatoire<double>(5.5, 4);
    aleatoire(5.5, 4.0);
    aleatoire(5, 4);
    Autre chose étrange, quand je remplace le minimumd(valant 1.24) de aleatoire(minimumd,maximum), par minimum(valant 5), la console m'affiche systematiquement le chiffre 5, mais tout le temps (j'ai essayé 40 fois pour voir si c'était pas juste de la chance)
    Oui, il y avait un piège
    Je te laisse chercher un peu
    Un indice : division d'entiers.

  13. #13
    Membre confirmé
    Profil pro
    Lycéen
    Inscrit en
    Novembre 2009
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2009
    Messages : 67
    Par défaut
    je viens de me rendre compte que le deuxième argument était inutile.
    Egalement, pour le double ca fonctionne, mais le chiffre ne varie pas beaucoup. ca change qu'apres 3 chiffre apres la virgule.

    Pour la fonction avec la division d'entier, je cherche toujours

    En décomposant le calcul:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (5 + rand()) * (5 / RAND_MAX)
    (j'ai pris 5 mais c'est juste un exemple)

    5+ rand = 18406 (par exemple)
    5/RAND_MAX) = 0 !

    Donc maintenant, je n'obtiens plus 5, mais 0 à chaque fois

  14. #14
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Cette entrée de la FAQ pourrait t'aider.

    Sinon ce n'est pas : (5 + rand()) * (5 / RAND_MAX) mais 5 + rand() * (5 / RAND_MAX)

  15. #15
    Membre confirmé
    Profil pro
    Lycéen
    Inscrit en
    Novembre 2009
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2009
    Messages : 67
    Par défaut
    Là je seche completement lol

  16. #16
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 202
    Par défaut
    La division entre entier est la division euclidienne, qui a pour résultat un entier.
    Elle possède un reste.

    Pour tous entiers p et q, p = (p/q)*q + p%q.
    5 = (5/2)*2 + 5%2 = 2*2 + 1
    5 = (5/10)*10 + 5%10 = 0*10 + 5

    RAND_MAX est plus grand que 5, donc 5/RAND_MAX = 0.

    La solution est de forcer la division à être un nombre flottant, en convertissant l'un de ses arguments en float ou double (le 5, de préférence)

  17. #17
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2012
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2012
    Messages : 63
    Par défaut
    pour un nombre aléatoire

    rand()%t;

    avec t la valeur max de ton rand

  18. #18
    Membre Expert
    Homme Profil pro
    Inscrit en
    Décembre 2010
    Messages
    734
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 734
    Par défaut
    Citation Envoyé par takago Voir le message
    pour un nombre aléatoire

    rand()%t;

    avec t la valeur max de ton rand
    As tu parcouru la thread ? Juste les premiers posts?

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/10/2008, 09h33
  2. fonction aléatoire sous l'AS 400
    Par tenah34 dans le forum AS/400
    Réponses: 6
    Dernier message: 02/09/2008, 17h08
  3. Fonction aléatoire pas ordinaire
    Par gotrunkssj dans le forum C
    Réponses: 5
    Dernier message: 21/01/2008, 13h09
  4. Excel fonction aléatoire
    Par Biker-Robby dans le forum Excel
    Réponses: 3
    Dernier message: 11/12/2007, 09h17
  5. Fonctions aléatoires pour caractères
    Par IDE dans le forum C
    Réponses: 14
    Dernier message: 13/05/2007, 15h06

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