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 :

simple question - taille integer


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Juillet 2008
    Messages : 55
    Points : 45
    Points
    45
    Par défaut simple question - taille integer
    Bonjour,

    voilà, je met au point une fonction pour saisir un entier signé sur 16 bits.

    C'est juste une fonction pour controler la saisie au clavier. J'aimerais que le nombre entier ne dépasse pas sa taille. Donc je valide l'entrée seulement si le nombre qui risque d'etre entré ne dépasse pas 32767.

    Pour valider le nombre je fait un test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if((nombre*10+(int)saisie-0X30)<=32767) //le test de validation,-0X30 pour passer de l'ascii à une valeur numérique
    {	
    	printf("%c",saisie); //si ça passe, j'écris a l'écran
    	if(nombre>0) //
    		nombre*=10; //si on est a 6 et qu'on écris, alors ça devient 60...
    	nombre+=((int)saisie-0X30); // et j'y ajoute la valeur entré au clavier 
    }
    Tout ceci juste pour ne pas dépasser les fameux 32767. Ma question est tout simplement, que se passe-t-il dans le test lorsque j'écris
    "nombre*10+(int)saisie-0X30"?
    La valeur créé peut-être supérieur à 32768, comment le processeur gère ça? Il n'a pas de limite? Ou le fait-il dans une sorte de variable temporaire égale à un int? Si c'est ce dernier cas, tout ça ne sert peut-être a rien car même dans le test je dépasserais la taille non?

    Bref si quelqu'un a une réponse à ça, merci d'avance.

  2. #2
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Citation Envoyé par h3llmo Voir le message
    Ma question est tout simplement, que se passe-t-il dans le test lorsque j'écris
    "nombre*10+(int)saisie-0X30"?
    La valeur créé peut-être supérieur à 32768, comment le processeur gère ça? Il n'a pas de limite?
    Si.
    Citation Envoyé par h3llmo Voir le message
    Ou le fait-il dans une sorte de variable temporaire égale à un int?
    Oui.
    Citation Envoyé par h3llmo Voir le message
    Si c'est ce dernier cas, tout ça ne sert peut-être a rien car même dans le test je dépasserais la taille non?
    Dépasser la taille de quoi ? Tu veux dire dépasser 32767 ? Oui, l'expression peut dépasser 32767... Mais c'est bien ce que tu veux non ? Détecter ce cas pour refuser la saisie.

    Au fait c'est 0x30, pas 0X30.

  3. #3
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par matafan Voir le message
    Au fait c'est 0x30, pas 0X30.
    Non, les 2 sont valides:
    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
      6.4.4.1 Integer constants
      Syntax
    1        integer-constant:
                     decimal-constant integer-suffixopt
                     octal-constant integer-suffixopt
                     hexadecimal-constant integer-suffixopt
             decimal-constant:
                     nonzero-digit
                     decimal-constant digit
             octal-constant:
                     0
                     octal-constant octal-digit
             hexadecimal-constant:
                     hexadecimal-prefix hexadecimal-digit
                     hexadecimal-constant hexadecimal-digit
             hexadecimal-prefix: one of
                     0x 0X
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  4. #4
    Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Juillet 2008
    Messages : 55
    Points : 45
    Points
    45
    Par défaut
    Merci pour les réponses, oui 0X30 fonctionne bien, a moins qu'il y ait une bonne raison de pas le faire...
    Citation Envoyé par matafan Voir le message
    Si.

    Oui.

    Dépasser la taille de quoi ? Tu veux dire dépasser 32767 ? Oui, l'expression peut dépasser 32767... Mais c'est bien ce que tu veux non ? Détecter ce cas pour refuser la saisie.

    Au fait c'est 0x30, pas 0X30.
    Après une après-midi de test, j'en ai conclu que non il ne peut pas dépasser la taille même dans l'expression, même si je ne sais toujours pas comment la "variable temporaire" est géré dans le calcul de l'expression. Mais apparement il y une limite, car lorsqu'on dépasse cette limite on revient au début, bref comme si on avait une variable de un octet -> FF+1=00 avec éjection du bit de poids fort.

    Le problème était que je n'arrivais pas a tester le dépassement comme on pourrait le faire en assembleur avec les flags.

    Du coup la saisie était validée car la valeur testée en cas de dépassement devenait forcément plus petite que la limite.

    Du coup j'ai résolu mon problème en testant si cette valeur était justement plus petite que l'ancienne, si c'était le cas c'est qu'il y avait eu dépassement et donc je ne validais pas. Enfin a peu de chose près, il y avait quelques autres arrangements, j'ai additionné dix fois la valeur plutot que de la multiplier directement par dix...
    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
     
    if(saisie>=0X30&&saisie<=0X39)
    {		
    	nombreBak=nombre;
    	for(j=0;j<9;j++)
    	{
    		controle=1;
    		nombre+=nombreBak;				
    		if((nombre+(saisie-0X30))<nombreBak)
    		{
    			controle=0;
    			nombre=nombreBak;
    			break;
    		}	
    	}
    etc...

  5. #5
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Il doit y avoir quelque chose que tu ne nous dit pas. L'expression (nombre*10+(int)saisie-0X30) ne manipule que des int. Il n'y a aucune raison qu'elle boucle à 0xff, à part si sur ta machine les int font 8 bits.

    Merci nicolas.sitbon, je ne savais pas que 0X était aussi accepté. C'est la première fois que je vois ça.

  6. #6
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par h3llmo Voir le message
    voilà, je met au point une fonction pour saisir un entier signé sur 16 bits.

    C'est juste une fonction pour controler la saisie au clavier. J'aimerais que le nombre entier ne dépasse pas sa taille. Donc je valide l'entrée seulement si le nombre qui risque d'etre entré ne dépasse pas 32767.

    Tout ceci juste pour ne pas dépasser les fameux 32767.
    Y'a-t-il besoin de faire plus compliqué que :
    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
     
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
    static void fclean (char *line, FILE * fp)
    {
       char *p = strchr (line, '\n');
       if (p != NULL)
       {
          *p = 0;
       }
       else
       {
          int c;
          while ((c = fgetc (fp)) != '\n' && c != EOF)
          {
          }
       }
    }
     
    int main (void)
    {
     
       unsigned x;
       int err;
       do
       {
          char s[8];
     
          fgets (s, sizeof s, stdin);
          fclean (s, stdin);
          x = strtoul (s, NULL, 10);
     
          err = x > 0x7FFF;
          if (err)
             puts ("error");
       }
       while (err);
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    -1
    error
    12345678
    error
    32768
    error
    32767
     
    Process returned 0 (0x0)   execution time : 35.476 s
    Press any key to continue.
    Pas de Wi-Fi à la maison : CPL

  7. #7
    Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Juillet 2008
    Messages : 55
    Points : 45
    Points
    45
    Par défaut
    oui et non... c'est vrai que c'est sympa pour controler APRES la saisie. De plus tu fait appel a stdin et j'aimerais justement éviter d'appeler des fonctions de saisie comme celle là, ou scanf.

    Quand je dit que je veux controle la saisie, c'est au moment même, donc si la limite est 32767, et que la personne a tapé pour l'instant 3276, j'aimerais que les seul chiffres qui passent ensuite soiet égaux ou inférieurs à 7, dans le cas contraire je fait biper le pc et je n'affiche rien a l'écran.


    Citation Envoyé par matafan Voir le message
    Il doit y avoir quelque chose que tu ne nous dit pas. L'expression (nombre*10+(int)saisie-0X30) ne manipule que des int. Il n'y a aucune raison qu'elle boucle à 0xff, à part si sur ta machine les int font 8 bits.
    Oui elle ne manipule que des int signés. Donc si je tape 4000 et que je tape encore un zero, le test va d'abord multiplier le nombre par dix pour voir si ça ne dépasse pas. Seulement en multipliant par dix le résultat de l'expression dépasse la limite (car ça devient 40000) et boucle à nouveau, résultant de cela une valeur plus petite que la limite. Pour mon exemple, c'était juste un exemple sur un seul octet (et pas deux j'ai été trop vite) pour expliquer la boucle. Mes int sont sur 4 octet, la limite étant en fait 2147483647 en signé. Mais sur un autre PC ils sont sur 2 octet, limite de 32767 tjr en signé.

    Voilà ce que ça donne avec 4 octet si l'expression dépasse la limite:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Saisir un entier: Limite: 2147483647
    saisir:2147483648
    Entier saisi: -2147483648
    Ici en signé il va dans les négatif. En non signé avec la limite de 4 octets

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Saisir un entier: Limite: 4294967295
    saisir:4294967296
    Entier saisi: 0
    dans le deux cas, la saisie est validée, ce qui m'embête, pire on peut vraiment taper n'importe quoi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Saisir un entier: Limite: 4294967295
    saisir:9999999999999999999
    Entier saisi: 2313682943
    Donc pour résumer, ce que je voulais c'était saisir un entier sur 16 bits (ou n'importe maintenant) sans dépasser la taille de l'int et cela en vérifiant ce que tape la personne au moment même.

    Je dit pas que ma solution est bonne, mais j'y suis arrivé ça marche plutot bien, et maintenant pour n'importe quel int, le pc refuse la saisie en cas de dépassement. Et oui il y avait surement plus facile, ou un autre code de pro déjà fait, mais on peut se lancer de défis parfois non?

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 13/10/2005, 12h46
  2. [langage] simple question ...
    Par perlgirl dans le forum Langage
    Réponses: 13
    Dernier message: 16/07/2004, 13h22
  3. PageControl -> Une simple question
    Par Invité dans le forum C++Builder
    Réponses: 4
    Dernier message: 08/05/2004, 09h19
  4. Réponses: 9
    Dernier message: 29/07/2003, 14h41

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