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 :

GCC et les entiers :]


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Par défaut GCC et les entiers :]
    Bonjour,

    J'aimerais obtenir des précisions sur le comportement de ce programme compilé avec GCC :

    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
     
    #include <stdio.h>
    #include <math.h>
    #include <ctype.h>
     
    short int ctoi(const int c) {
    	if (c == '0')
    		return 0;
    	else if (c == '1')
    		return 1;
    	else if (c == '2')
    		return 2;
    	else if (c == '3')
    		return 3;
    	else if (c == '4')
    		return 4;
    	else if (c == '5')
    		return 5;
    	else if (c == '6')
    		return 6;
    	else if (c == '7')
    		return 7;
    	else if (c == '8')
    		return 8;
    	else if (c == '9')
    		return 9;
    	else	
    		return c;
    }
     
    int funcn(void) {
    	char c;
    	int n;
    	int i, j;
    	i = n = 0;
    	while ((c = getchar()) != '\n' && c != EOF) {
    		if (isdigit(c)) {
    			n += (ctoi(c) * pow(10, i));
    			++i;
    		}
    	}
    	printf("---+ %d\n", n);
    	return n;
    }
     
     
    int main(void) {
    	unsigned int nl, nc;
    	printf("NUM1> ");
    	nl = funcn();
    	printf("\n\nNUM2> ");
    	nc = funcn();
    	printf("%u %u\n", nl, nc);
    	return 0;
    }
    Le programme a pour SIMPLE but d'inverser les chiffres composant le nombre que l'on fourni en entrée au programme.

    Le problème, c'est qu'avec GCC, le nombre inversé n'est pas exactement l'inverse du nombre concerné. Généralement, c'est comme si le programme soustrayais 1 ou 2 au nombre inversé.

    Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    NUM1> 1234
    ---+ 4320
     
     
    NUM2> 56789
    ---+ 98763
    4320 98763
    Les réponses devraient évidemment être 4321 et 98765...

    Qu'est qui cause ces erreurs?
    Comment palier à ce problème?

    Notez que ce problème fait son apparition SEULEMENT avec GCC.
    Compilé avec ICC (Intel) et CL (Microsoft), le programme se comporte comme il se doit.


    Merci,

    Sincèrement,

    Array

  2. #2
    Membre éclairé Avatar de je®ome
    Inscrit en
    Octobre 2005
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 285
    Par défaut
    Salut,

    à priori, je ne vois pas pourquoi cela ne marcherait pas.
    Avec gcc version 4.1.2, il n'y a pas de problème.

    NUM1> 1234
    ---+ 4321


    NUM2> 456789
    ---+ 987654
    4321 987654
    Essaie de voir ce que pow te renvoie pour pow(10,0).
    Ma version râle si je ne compile pas avec l'option -lm
    (à cause de #include <math.h>) ....
    Peut-être que l'option -Wall peut te donner plus d'informations.....

    Sinon, faire plus de print

  3. #3
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    euh.....

    Une valeur entre ' ' est un CARACTERE, pas un entier...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    short int ctoi(const int c) {
    	if (c == 0)
    		return 0;
    	else if (c == 1)
    		return 1;
    marcherait beaucoup mieux....

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Une valeur entre ' ' est un CARACTERE, pas un entier...
    C'est un entier du type int

  5. #5
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Salut,

    Des problèmes de type un peu partout dans ce code ...mais le plus sérieux est celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    n += (ctoi(c) * pow(10, i));
    "pow" retourne un double !! ...tandis que le "n" est de type int sachant que la conversion float vers int provoque une perte de précision voilà ce que tu obtiens pour chaque tour de boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    1=(1)
    21=1+(20)
    320=1+20+(299) 
    4320=1+20+299+(4000)
    Essaie avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    <...>
    double n;
    <...>
    printf("---+ %d\n", (int)n);
    <...>

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par diogene Voir le message
    C'est un entier du type int
    oui mais pas identique entre valeur numerique et valeur du caractere (voir ci-dessus)...

    http://www.asciitable.com/

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    ok j'ai relu son code...

    C'est ok parce qu'il prend la representation..

    Mais personellement, j'aurais trouve beaucoup plus clair de mettre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int ctoi ( char c )
    {
    ....
    }
    ou alors

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int ctoi (int c )
    {
      if ( c < 48 || c > 57 )
          return NaN ;
      else
          return ( c - 48 );
    }

  8. #8
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    euh.....

    Une valeur entre ' ' est un CARACTERE, pas un entier...
    On est bien d'accord, 'A' est une constante entière de type int dont la valeur est 65 (encodage ASCII), non?

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Thierry Chappuis Voir le message
    On est bien d'accord, 'A' est une constante entière de type int dont la valeur est 65 (encodage ASCII), non?

    Thierry
    Absolument....

    Mais en entree de sa fonction, le PO a un int..

    qu'il compare ensuite a la valeur ASCII.... hum humm.....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	if (c == '0')
    		return 0;
    	else if (c == '1')
    		return 1;
    si c (entier) est 1, son caractere ASCII est 49... et reciproquement...

    c == '1' voudrait dire que c = 49.

    Inversement

    c == 1 signifie c = SOH en ASCII...

Discussions similaires

  1. gcc et les normes
    Par gnto dans le forum C
    Réponses: 2
    Dernier message: 13/06/2006, 00h18
  2. fstream >> probleme avec les entiers
    Par Acropole dans le forum SL & STL
    Réponses: 6
    Dernier message: 01/12/2005, 10h36
  3. Gcc et les fonctions
    Par fregolo52 dans le forum Linux
    Réponses: 9
    Dernier message: 09/08/2004, 18h55
  4. Sélectionner tous les entiers dans une fourchette
    Par ludo.guy dans le forum Langage SQL
    Réponses: 5
    Dernier message: 16/07/2004, 09h15
  5. FormatFloat pour les entiers !?
    Par Lung dans le forum Langage
    Réponses: 5
    Dernier message: 10/04/2003, 15h20

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