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 :

Nombre négatif quand je convertis int en char


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Espagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 145
    Par défaut Nombre négatif quand je convertis int en char
    Voila mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        srand(time(NULL));
        int a = rand() % 256;
        char c =  a;
        cout << (int)c << endl;
    Je cherche à avoir aléatoirement un char. Du coup, je génère un int entre 0 et 255 avec rand() que je stock alors dans un char.
    Mais voila que quand je l'imprime je me retrouve parfois avec des valeurs négatives.... d'où cela peut bien venir???

  2. #2
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    un char est signé, donc peut être négatif (si je me souviens bien de -127 à +127). Si tu ne veux pas de valeur négative, prend un unsigned char.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Espagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 145
    Par défaut hmm
    hmmm d'accord, je vois d'où viens mon problème. Mais j'arrive pas à le résoudre quand même...

    Voici où je m'en sert au fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class RandInt{
        private:
            struct drand48_data dp;
        public:
            RandInt();
            int rand();
            void generateRandomString(char *a, int len);
            void generateDataSet(const int numKeyWords, const int numRecords, char* a, char *keys);
    };
    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
     
    int RandInt::rand(){
          double a = 0.0;
          drand48_r(&dp,&a);
          int ans = (int)(a*((int)1<<30));
          cout << ans % 256 << endl; 
          return ans;
    }
     
    //generates a string of length len and stores it in *a
    void RandInt::generateRandomString(char *a, int len){
      for(int j = 0; j < len; j++){
          *(a+j) = (unsigned char) (rand() % 256 );
          cout << (int)*(a+j) << endl;
      }
    }
    Je n'ai pas mis toutes les méthodes. Mais bref, mon objectif est d'utiliser cette classe de générateur de nombre aléatoire pour créer des chaînes de charactères.

    Rand::rand() créé un chiffre entre 0 et 2^30 (je m'en sert aussi pour autre chose, ce qui explique pourquoi je fais pas directement 0 à 255).

    Ensuite generateRandomString(char* a, int len) stock dans a une chaine de charactères aléatoires.
    Maintenant, quand j'imprime la valeur de ans dans rand avant de la renvoyé, j'ai bien ce qu'il me faut. Par contre, quand j'imprime ce qui a été stocké dans à l'addresse a+j ben je me retrouve avec des trucs négatifs...

  4. #4
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Si tes chaînes de caractère n'ont pas besoin d'être alphabétiques, alors tu n'as pas à t'occuper du signe.
    Sinon en plus du signe, il te faut vérifier que chaque char est compris entre 'a' et 'Z'.
    Si en plus tu veux que tes chaînes soient cohérentes au niveau syllabique, il te faut une liste de toutes les syllabes que tu veux considérer et que tu fasses ton random sur cette liste, avec un nombre aléatoire de syllabes.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Espagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 145
    Par défaut
    Je souhaite juste générer une chaine de charactères pouvant contenir n'importe quel des 256 charactères ASCII (câd en décimal de 0 à 255)...

  6. #6
    Membre chevronné

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 426
    Par défaut
    ..

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    un char est signé, donc peut être négatif (si je me souviens bien de -127 à +127). Si tu ne veux pas de valeur négative, prend un unsigned char.
    Disons plus précisément que char peut être équivalent à signed char, ou à unsigned char, selon la préférence du compilateur. Et il existe des compilateurs ayant choisi le premier, d'autres ayant choisi le second, d'autres dont le choix dépend d'une option de compilation.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Espagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 145
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Disons plus précisément que char peut être équivalent à signed char, ou à unsigned char, selon la préférence du compilateur. Et il existe des compilateurs ayant choisi le premier, d'autres ayant choisi le second, d'autres dont le choix dépend d'une option de compilation.
    D'accord. Mais au final, comment je peux m'assurer que je ne créé uniquement des chars de 0 à 255?
    Je résume que je géner d'abord aléatoire un int entre 0 et 2^30 avec la fonction RandInt::rand(), puis je veux faire un cast du style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void RandInt::generateRandomString(char *a, int len){
      for(int j = 0; j < len; j++){
          *(a+j) = (char) (rand() % 256 );
          cout << (int)*(a+j) << endl;
      }

  9. #9
    Membre Expert Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Par défaut
    On te parle d'unsigned char, pourquoi ne fais-tu pas ca ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void RandInt::generateRandomString(unsigned char *a, int len){
      for(int j = 0; j < len; j++){
          *(a+j) = (unsigned char) (rand() % 256 );
          cout << (int)*(a+j) << endl;
      }

  10. #10
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2009
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Espagne

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 145
    Par défaut
    Citation Envoyé par fregolo52 Voir le message
    On te parle d'unsigned char, pourquoi ne fais-tu pas ca ? :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void RandInt::generateRandomString(unsigned char *a, int len){
      for(int j = 0; j < len; j++){
          *(a+j) = (unsigned char) (rand() % 256 );
          cout << (int)*(a+j) << endl;
      }
    J'ai essayé ça mais j'ai toujours le même problème, c'est à dire que a+j peut prendre des valeurs négatives...
    Et pour répondre à dragonjoker59, au fait, je génère plein de chaînes et après je les tri.
    J'utilise le tri radix et grosso modo, à un moment dans le tri j'incrémente des cases d'un tableau, cases dont les index correspondent à la valeur du char. Je sais pas si c'est très clair, grosso modo à un moment je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
          array.at( keys[i][h] );
    //en gros keys est un vecteur de char*. keys[i][h] renvoie la valeur du char
    //en position h dans la chaine keys[i]. Et c'est là où j'ai un problème si celle-ci
    //est négative...

  11. #11
    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
    Salut,
    Citation Envoyé par ncheboi Voir le message
    D'accord. Mais au final, comment je peux m'assurer que je ne créé uniquement des chars de 0 à 255?
    => en utilisant unsigned char cf réponse de fregolo52
    => ou en utilisant un type avec une plage de valeur garantie contenant [0;255[ : short/int/long et ne gardant que les valeurs qui t'intéressent

  12. #12
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Au final, si c'est pour afficher ta chaîne de caractères, ne t'occupe pas du signe, sur une 'char', qui est apparemment 'signed' sur ton compilo, tu as des valeurs positives et des valeurs négatives, mais à l'affichage il n'y aura pas de problème.
    Au niveau du codage, sur un 'signed char', le bit de poids fort sert au signe (0=>'+', 1=>'-'), alors que sur un 'unsigned char' ce même bit sert à passer au delà de 128. Dans une chaîne de caractères, ça n'a aucune importance.
    Lors de ta génération aléatoire, comme tu passes ton résultat à un 'signed char', quand tu essaies de voir la valeur de ce 'char', tu vois la valeur interprétée en 'signed char' et donc tes valeurs qui étaient supérieures à 127 passent en négatif.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

Discussions similaires

  1. Méthode Character.getNumericValue(char c) d'un nombre négatif
    Par freeway57 dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 17/06/2014, 11h17
  2. [D7 Ent. / XP] Trunc() sur un nombre négatif
    Par Magnus dans le forum Langage
    Réponses: 14
    Dernier message: 17/06/2005, 16h45
  3. [C++] Conversion de int en char* ou SetDlgItemText()
    Par lastcheper dans le forum MFC
    Réponses: 3
    Dernier message: 11/04/2005, 17h46
  4. [SQL] Convertir un champ INT en CHAR dans un SELECT ?
    Par webtheque dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 17/03/2005, 14h45
  5. [68000] EXT nombre négatif
    Par fastzombi dans le forum Autres architectures
    Réponses: 2
    Dernier message: 02/05/2004, 12h17

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