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 :

Un problème que ma logique ne peut pas résoudre


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 13
    Par défaut Un problème que ma logique ne peut pas résoudre
    Bonjour, dans le cadre de mes études, je suis amené à créer ce petit programme qui, à partir d'un int, affiche un char. En révisant, je me suis apercue que mon programme était DÉGUELASSE, je l'ai donc refait, en passant par la récursive. Youpi, le programme ne tient plus qu'en une seule fonction et quelques lignes. Seulement, voilà le problème, le programme a une faille : lorsque je lui envoie -2 147 483 648, ce foutu prog me donne le résultat avec deux - : --2147483648.

    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
     
    void	putchar(char c)
    {
      write(1, &c, 1);
    }
     
    void	put_nbr(int nb)
    {
      int	nbr;
     
      if (nb > 0)
          nb = -nb;
      else
        putchar('-');
      nbr = nb % 10;
      putchar('n');
      if (nb < -9)
      	put_nbr(-nb / 10);
      putchar(-nbr + 48);
    }
     
    int	main()
    {
      put_nbr(-2147483648);
      putchar('\n');
    }
    Une petite aide serait la bienvenue mais sans me donner la réponse s'il vous plaît ^^

    En tout cas très beau travail de la part de vous tous et j'espère que j'aurais bientôt le niveau pour participer

  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,

    Pourquoi avoir "réimplémenté" putchar, est-ce que cela fait parti de l'exercice ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (nb > 0)
          nb = -nb;
      else
        putchar('-');
    Ne serait-ce pas plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if(nb < 0)
    {
              nb = -nb;
              putchar('-');
    }
    ?

    EDIT : d'ailleurs je ne comprend pas pourquoi tu veux mettre ton nombre en négatif. N'est-ce pas plus simple de passer par des nombres positifs ?

    Sinon au lieu de faire +48 ce qui n'est pas très clair, il vaut mieux faire : +'0'.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 13
    Par défaut
    En faisant comme tu me le conseille, je me heurte à un overflow si je veux afficher le nombre -2147483648, car je ne peux pas le repasser en positif. C'est pour cela que je passe par le négatif.

    Je ne comprend pas ta question sur la réimplémentation de putchar. Pourrais-tu être plus clair s'il-te-plaît ?

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 13
    Par défaut
    enfin... Le compilateur ne me préviens même pas de l'overflow, c'est juste que repasser -2147483648 en positfi n'est pas possible puisque les int s'arrêtent à la valeur 2147483648

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 13
    Par défaut
    ah oui, pardon, est une indication, pour savoir quand est-ce que mon programme me rajoute le -, ainsi j'obtiens :

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 13
    Par défaut
    oui mais c'est bien sûr passer par une autre fonction, j'avais tellement envie de voir tout tenir le minimum de ligne que j'en avais ommis l'hypothèse de faire une autre fonction. Merci de me l'avoir rapellé. Résolu donc. Merci de ton aide.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par erogan Voir le message
    enfin... Le compilateur ne me préviens même pas de l'overflow, c'est juste que repasser -2147483648 en positfi n'est pas possible puisque les int s'arrêtent à la valeur 2147483648
    En fait, les int peuvent coder 4294967296 valeurs qui vont de -2147483648 à 2147483647 (à cause du 0 qui prend une position).
    D'où effectivement le cas extrême quand ton nombre vaut pile poil -2147483648 lequel ne possède pas d'équivalent positif. Toutefois tu peux aussi réfléchir dans l'autre sens et considérer que tu n'as que des négatifs et faire le calcul sur la base de ce prédicat, quitte à convertir les positifs éventuels en négatifs. Là tu n'auras pas de problème de cas extrême à gérer...
    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]

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    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 397
    Par défaut
    Attends, mais oui!

    On peut passer le nombre en non-signé dès qu'on l'a rendu positif!
    Le -2147483648 signé et le 2147483648 ont la même représentation binaire...
    Code C : 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
    #ifdef _WIN32
    	/*unistd.h n'existe pas*/
    	#define _CRT_NONSTDC_NO_WARNINGS
    	#include <io.h> /*pour write()*/
    	#define STDOUT_FILENO 1
    #else
    	#include <unistd.h> /*pour STDOUT_FILENO*/
    #endif
    #include <limits.h> /*pour INT_MAX et INT_MIN*/
     
    void putchar(char c)
    {
    	/*Ce n'est pas parce qu'on est à EPITA qu'on a le droit de coder comme un porc avec des nombres magiques.*/
    	write(STDOUT_FILENO, &c, 1);
    }
     
    void put_unbr(unsigned int unb)
    {
    	unsigned int udigit = unb % 10u;
    	if (unb > 9)
    		put_unbr(unb / 10u);
    	putchar((char)udigit + '0'); /*Voir commentaire dans putchar*/
    }
     
    void put_nbr(int nb)
    {
    	if (nb < 0)
    	{
    		putchar('-');
    		nb = -nb;
    	}
    	put_unbr(nb);
    }
     
    int main(void)
    {
    	put_nbr(INT_MAX);
    	putchar('\n');
     
    	put_nbr(42);
    	putchar('\n');
     
    	put_nbr(1);
    	putchar('\n');
     
    	put_nbr(0);
    	putchar('\n');
     
    	put_nbr(-1);
    	putchar('\n');
     
    	put_nbr(-42);
    	putchar('\n');
     
    	put_nbr(INT_MIN);
    	putchar('\n');
    	return 0;
    }
    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
    Membre émérite
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Par défaut
    Citation Envoyé par Médinoc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    /*unistd.h n'existe pas*/
    Il y en a une implémentation sous Cygwin, et même sur MinGW.

    Citation Envoyé par Sve@r Voir le message
    En fait, les int peuvent coder 4294967296 valeurs qui vont de -2147483648 à 2147483647 (à cause du 0 qui prend une position).
    Ce n'est pas parce qu'on code pour POSIX qu'on doit faire abstraction de la taille des types. Certes la représentation en complément à deux est garantie (selon mes souvenirs, ce n'est pas explicitement dit, mais on peut le déduire à partir de certaines données), mais un int n'est pas toujours codé sur 32 bits. Du fait des représentations en complément à 1 et signe et magnitude acceptées par la norme, il faudrait même parler de -2147483647.
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

  10. #10
    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
    Déjà la vérification du signe ne doit se faire qu'une seule fois donc on peut envisager quelque chose comme :

    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
    void affiche_nombre(int val)
    {
                   unsigned int newVal = val;
                   if(val < 0)
                   {
                          putchar("-");
                          newVal = ~newVal; //équivalant à newVal = -val; car on code les signed sur du complément à 2.
                   }
                   m_affiche_nombre( newVal);
    }
     
    void m_affiche_nombre(unsigned int val)
    {
    //....
    }
    Sinon, tu peux faire le test du signe juste après avoir obtenu le premier chiffre et divisé ton nombre.

    Pour putchar, c'est juste que cette fonction existe déjà :
    http://man.developpez.com/man3/puts.3.php

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

Discussions similaires

  1. problèmes de logique ! ne fait pas dans l'ordre.
    Par djibb dans le forum Tkinter
    Réponses: 3
    Dernier message: 29/05/2007, 17h06
  2. Réponses: 7
    Dernier message: 07/01/2007, 12h16
  3. [Tableaux] un problème que je ne vois pas?
    Par Skeud007 dans le forum Langage
    Réponses: 11
    Dernier message: 07/10/2006, 23h24
  4. [JDOM] Probléme que je ne comprend pas
    Par kaninama dans le forum Format d'échange (XML, JSON...)
    Réponses: 5
    Dernier message: 23/05/2006, 15h01
  5. problème que je n'arrive pas à résoudre de façon récursive
    Par miam dans le forum Algorithmes et structures de données
    Réponses: 9
    Dernier message: 31/07/2004, 11h21

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