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 :

Récupération du bit de signe


Sujet :

C++

  1. #1
    Membre éprouvé
    Inscrit en
    Mai 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 196
    Par défaut Récupération du bit de signe
    Bonjour,

    Je pense que je vais devoir plonger dans un mixe C++/ASM, mais le forum le plus approprié me parait être celui-ci .

    Alors voila, je voudrais récupérer le bit de signe d'un entier. Ma première idée était de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    bool bit_de_signe = monEntier <<1; //BIGENDIAN
    Problème, je ne récupère pas le bit de signe, mais je le perds justement (remémoration de mes cours d'ASM en DUT ~7ans ).

    Du coup je voulais savoir si je peux récupérer le flag qui récupère ce bit ? J'ai vu que c'était le flag CF.

    En fait je voudrais savoir si y a une manière "simple" et surtout efficace de le faire ...

    Explication :
    Au lieux de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    for(...)
    {
         if( maVar==-1 )
            X = val_0;
         else if( maVar ==1 )
            X = val_1;
         else
            X = val_2;
    }
    Je comptais faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int conv[]={val_1, val_2}
    for(...)
        X=(bitSign==true)?val_0:conv[maVar]
    Le problème de de récupéré efficacement le bit de signe pour que ma méthode illisible soit elle même efficace ...

    Merci d'avance.

  2. #2
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    Il ne faut, surtout pas,, travailler en assembleur, car tu finirais par te trouver dans une situation tout à fait impossible qui consiste à devoir prévoir autant de code assembleur qu'il n'y a d'architectures/os différents à gérer

    Le plus facile est de te baser sur un masque binaire, tout simplement...

    Mais, pour cela, il faut connaitre le nombre de bits utilisés

    Par exemple, sur un entier signé codé sur 32, tu sais que toute valeur supérieur à (en hexadécimal) 0x70000000 va indiquer que le bit de signe est à 1.

    Tu peux donc écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int i; //je considère qu'un int fait 32 bits ;)
    /*...*/
    if( i & 0x70000000)
        cout<<"bit de signe à 1";
    else
        cout<<"bit de signe à 0";
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre éprouvé
    Inscrit en
    Mai 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 196
    Par défaut
    Merci koala01,

    Tout à fait d'accord pour la généricité des architecture, même si à priori mon soft devrait tourner seulement sur x86 (j'aimerais tâter le CELL de la PS3, mais pour avoir la SDK ça a l'air d'être un enfer ...)

    Par contre, pour ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int i; //je considère qu'un int fait 32 bits ;)
    /*...*/
    if( i & 0x70000000)
        cout<<"bit de signe à 1";
    else
        cout<<"bit de signe à 0";
    j'ai une interrogation :

    Si i vaut 1 -> i vaut 00000001h.
    Si i vaut -1 -> i vaut 80000001h.

    hors
    00000001h & 70000000h = 00000000h
    et
    80000001h & 70000000h = 00000000h

    Nan ?

    Le mask ne devrait pas plutôt être 80000000h ?

    Par contre je suis toujours intéressé de savoir comment on récupère un flag ASM en C++ ... Culture G(eek) quoi .

    Merci encore.

  4. #4
    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
    Citation Envoyé par Clercq Voir le message
    j'ai une interrogation :

    Si i vaut 1 -> i vaut 00000001h.
    Si i vaut -1 -> i vaut 80000001h.
    En général, c'est le complément à 2 :
    Si i vaut 1 -> i vaut 00000001h.
    Si i vaut -1 -> i vaut FFFFFFFFh.

    Citation Envoyé par Clercq Voir le message
    hors
    00000001h & 70000000h = 00000000h
    et
    80000001h & 70000000h = 00000000h

    Nan ?
    Nan à cause du complément à 2
    Citation Envoyé par Clercq Voir le message
    Le mask ne devrait pas plutôt être 80000000h ?
    Mais oui car 0x80000000 == (int)-2147483648
    donc faut bien retrouver son signe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    0x80000000h & 70000000h = 00000000h // KO
    0x80000000h & 80000000h = 80000000h // OK
    Citation Envoyé par Clercq Voir le message
    Par contre je suis toujours intéressé de savoir comment on récupère un flag ASM en C++ ... Culture G(eek) quoi .
    Je ne sais pas. Quelque chose comme ça peut être ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    asm_
    {
    // puis code assembleur à voir avec l'assembleur !
    }

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par Clercq Voir le message
    Merci koala01,

    Tout à fait d'accord pour la généricité des architecture, même si à priori mon soft devrait tourner seulement sur x86 (j'aimerais tâter le CELL de la PS3, mais pour avoir la SDK ça a l'air d'être un enfer ...)

    Par contre, pour ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int i; //je considère qu'un int fait 32 bits ;)
    /*...*/
    if( i & 0x70000000)
        cout<<"bit de signe à 1";
    else
        cout<<"bit de signe à 0";
    j'ai une interrogation :

    Si i vaut 1 -> i vaut 00000001h.
    Si i vaut -1 -> i vaut 80000001h.

    hors
    00000001h & 70000000h = 00000000h
    et
    80000001h & 70000000h = 00000000h

    Nan ?

    Le mask ne devrait pas plutôt être 80000000h ?

    Par contre je suis toujours intéressé de savoir comment on récupère un flag ASM en C++ ... Culture G(eek) quoi .

    Merci encore.
    Oui, au temps pour moi... c'est bien 0x80000000 qu'il faut utiliser comme masque

    Ceci dit, j'aurais tendance à faire exactement de la même manière en assembleur, plutôt que d'essayer de récupérer le flag de dépassement
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre éprouvé
    Inscrit en
    Mai 2006
    Messages
    196
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 196
    Par défaut
    Oki oki, merci à toi.

  7. #7
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    52
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

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

    Informations forums :
    Inscription : Juin 2009
    Messages : 52
    Par défaut
    Salut,

    -1 sur 32 bits s'écrit 1111 1111 1111 1111 1111 1111 1111 1111 et non 80000001h

    Mais le mask est bien 80000000h

    Pour récupérer le bit de signe, il y a aussi le décalage de bit qui évite le &logique:

    int signe = i >>31;

    Fred

  8. #8
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par fredremy68 Voir le message
    Salut,

    -1 sur 32 bits s'écrit 1111 1111 1111 1111 1111 1111 1111 1111 et non 80000001h
    Le problème vient du fait que tu utilise ici deux bases différente, ce qui n'arrange pas les choses, car -1 codé sur 32 bit en hexa, c'est 0xFFFFFFFF
    Mais le mask est bien 80000000h
    oui, parce que 0x80000000 a une valeur binaire dans laquelle seul le bit de poid le plus fort est à un et du fait des caractéristiques même du ET logique...
    Pour récupérer le bit de signe, il y a aussi le décalage de bit qui évite le &logique:

    int signe = i >>31;
    Aussi...

    Mais, dans l'ensemble, étant donné qu'il s'agit de repérer toute valeur dont la représentation hexadécimale est suppérieure à 0x80000000, l'utilisation d'un masque vient plus naturellement en tête... même si le décalage de bit reste une possibilité

    Ce qu'il y a de bien avec l'informatique, c'est qu'il y a toujours plusieurs solutions pour arriver à un même résultat...

    Simplement, on peut constater que certaines seront plus ou moins efficaces que d'autres

    En parlant de ca, quelqu'un aurait il une idée de ce qui sera le plus efficace (en temps d'exécution, même s'il nous faut parler en "ticks" d'horloge) des deux
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    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 Clercq Voir le message
    Au lieux de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    for(...)
    {
         if( maVar==-1 )
            X = val_0;
         else if( maVar ==1 )
            X = val_1;
         else
            X = val_2;
    }
    Je comptais faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int conv[]={val_1, val_2}
    for(...)
        X=(bitSign==true)?val_0:conv[maVar]
    Les deux codes ne sont pas vraiment équivalents, en terme de valeur à prendre... Et surtout, j'ai de fort doutes que des opérateurs sioux donnent de meilleurs résultats que du code lisible équivalent. Quelle que soit la solution que tu emploieras, pourrais tu nous poster les résultats d'un bench comparatif ?
    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.

  10. #10
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Les deux codes ne sont pas vraiment équivalents, en terme de valeur à prendre... Et surtout, j'ai de fort doutes que des opérateurs sioux donnent de meilleurs résultats que du code lisible équivalent.
    +1000...

    Comme je le dis dans ma signature, la solution la plus simple est toujours la moins compliquée... Heu, la meilleure...

    Il ne faut pas oublier que l'ordinateur n'est, en définitive, que quelque chose de tellement idiot qu'il ne sait manipuler que des 0 et des 1, même s'il peut en manipuler énormément dans un très court laps de temps.

    Finalement, tout l'art de la programmation consiste, bien souvent, à arriver à se faire "aussi bête que l'ordinateur" pour arriver à lui faire comprendre les choses complexes que l'on attend de lui

    Par la suite, si, vraiment, la solution la plus simple s'avère être inadaptée de par les pauvres performances qu'elle présente, il est toujours temps de vérifier si d'autres solutions en présentent de meilleures...
    Quelle que soit la solution que tu emploieras, pourrais tu nous poster les résultats d'un bench comparatif ?
    Là aussi, je ne peux que plussoter...

    La première qualité d'un code, avant même de faire ce que l'on attend de lui, est, selon moi, d'être facilement compréhensible par la personne qui le lira...

    Dés lors, il s'agit, toujours selon moi, qu'une "ruse de sioux" présente un avantage réel en terme de performances pour en arriver à trouver grâce à mes yeux au dépend d'une solution, peut être moins performante, mais plus facilement lisible et compréhensible

    Mais bon, cela n'est qu'un avis personnel... que j'approuve et que je partage
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  11. #11
    Membre émérite
    Avatar de maxim_um
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    895
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 895
    Par défaut
    Salut,

    Citation Envoyé par koala01 Voir le message
    Mais bon, cela n'est qu'un avis personnel... que j'approuve et que je partage
    Il ne manquerait plus que tu n'approuves pas ton propre avis.

    Citation Envoyé par JolyLoic Voir le message
    Les deux codes ne sont pas vraiment équivalents, en terme de valeur à prendre... Et surtout, j'ai de fort doutes que des opérateurs sioux donnent de meilleurs résultats que du code lisible équivalent. Quelle que soit la solution que tu emploieras, pourrais tu nous poster les résultats d'un bench comparatif ?
    Non seulement les deux codes ne sont pas équivalents, en plus ils contiennent des instructions et des opérateurs inutiles et en plus "maVar" peut prendre la valeur "-1" !

    Du reste, ne peut-on pas simplement tester si son entier signé est négatif avec un opérateur de comparaison ?

Discussions similaires

  1. Complément à 2 qui ne change pas le bit de signe
    Par Bolboaa dans le forum Mathématiques
    Réponses: 3
    Dernier message: 15/05/2015, 10h24
  2. Existe-t'il un type Integer > 64 bits non signé
    Par colorid dans le forum Langage
    Réponses: 2
    Dernier message: 17/08/2012, 07h05
  3. Fonctionnement bit de signe, décalage
    Par atha2 dans le forum Général Java
    Réponses: 4
    Dernier message: 03/02/2012, 10h52
  4. [C#] Conversion chaîne vers entier signé 8 bits
    Par SesechXP dans le forum Windows Forms
    Réponses: 2
    Dernier message: 25/09/2006, 14h29
  5. [TP] Entier 32 bits non signé
    Par SkaMan dans le forum Turbo Pascal
    Réponses: 6
    Dernier message: 24/08/2005, 22h17

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