Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2622 connectés 

  FORUM HardWare.fr
  Programmation
  C

  positionner un bit sur un int

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

positionner un bit sur un int

n°1247174
meumeul
Stay Heavy
Posté le 16-11-2005 à 21:48:22  profilanswer
 

bonjour,
 
J'ai un int qui représente un tableau de 32 bits.
Si il y'a un 0 au bit 0 ca veut dire que la premiere case est vide
et un 1 si elle est pleine.
 
Je cherche une opération pour positionner le ième bit de mon int à 1
genre : set_bit(int mon_int, int position) => met a 1
            rem_bit(int mon_int, int position) => met a 0
 
j'ai trouvé ca sur le site koders

Code :
  1. #define SET_BIT(flag,bit) ((flag) |= (bit))
  2. #define REMOVE_BIT(flag,bit) ((flag) &= ~(bit))


mais je ne sais pas comment l'utiliser ...
si je fais dans mon code  mon_int = SET_BIT(mon_int, position_a_changer);
c'est censé marcher ??
 
 
je vous remercie ...
 

mood
Publicité
Posté le 16-11-2005 à 21:48:22  profilanswer
 

n°1247184
Emmanuel D​elahaye
C is a sharp tool
Posté le 16-11-2005 à 21:59:06  profilanswer
 

meumeul a écrit :

bonjour,
 
J'ai un int qui représente un tableau de 32 bits.
Si il y'a un 0 au bit 0 ca veut dire que la premiere case est vide
et un 1 si elle est pleine.
 
Je cherche une opération pour positionner le ième bit de mon int à 1
genre : set_bit(int mon_int, int position) => met a 1
            rem_bit(int mon_int, int position) => met a 0
 
j'ai trouvé ca sur le site koders

Code :
  1. #define SET_BIT(flag,bit) ((flag) |= (bit))
  2. #define REMOVE_BIT(flag,bit) ((flag) &= ~(bit))


mais je ne sais pas comment l'utiliser ...
si je fais dans mon code  mon_int = SET_BIT(mon_int, position_a_changer);
c'est censé marcher ??


Ceci est-il plus clair ?
 
http://mapage.noos.fr/emdel/clib/ed/inc/bits.h
 
Sinon, tu peux aussi recoder ta propre macro, c'est plus pédagogique...
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1247189
meumeul
Stay Heavy
Posté le 16-11-2005 à 22:04:03  profilanswer
 

Emmanuel Delahaye a écrit :

Ceci est-il plus clair ?
 
http://mapage.noos.fr/emdel/clib/ed/inc/bits.h
 
Sinon, tu peux aussi recoder ta propre macro, c'est plus pédagogique...


 
voila ce qui m'interesse dans ton .h
 
/* mask set/clear/toggle */
#define mSET(d_, m_) ((d_) |=  (m_))
#define mCLR(d_, m_) ((d_) &= ~(m_))
 
Il semblerait que ca soit la meme chose que j'ai trouvé. L' utilisation que j'ai décrite plus haut
est elle correcte ? j'ai du mal a la faire marcher en fait ...

n°1247214
meumeul
Stay Heavy
Posté le 16-11-2005 à 22:21:11  profilanswer
 

Sinon j'ai un autre idée :  
 

Code :
  1. int set_bit(int val, int pos) {
  2.      if (val < pow(2,pos)
  3.          val += pow(2,pos);
  4.     return val;
  5. }


 
Qu'en pensez vous ?

Message cité 1 fois
Message édité par meumeul le 16-11-2005 à 22:23:05
n°1247218
Emmanuel D​elahaye
C is a sharp tool
Posté le 16-11-2005 à 22:22:36  profilanswer
 

meumeul a écrit :

voila ce qui m'interesse dans ton .h
 
/* mask set/clear/toggle */
#define mSET(d_, m_) ((d_) |=  (m_))
#define mCLR(d_, m_) ((d_) &= ~(m_))
 
Il semblerait que ca soit la meme chose que j'ai trouvé. L' utilisation que j'ai décrite plus haut
est elle correcte ? j'ai du mal a la faire marcher en fait ...


d_, c'est la donnée (data)
m_, c'est le masque (mask)
 
La relation entre le masque et le numéro de bit est donné par la macro BIT()
 
Mettre le bit 3 de x à 1  

unsigned x = 0;
 
mSET (x, BIT(3));

ou, puisque les définitions existent...

mSET (x, bit3);


Message édité par Emmanuel Delahaye le 16-11-2005 à 22:24:41

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1247221
Emmanuel D​elahaye
C is a sharp tool
Posté le 16-11-2005 à 22:23:55  profilanswer
 

meumeul a écrit :

Sinon j'ai un autre idée :  
 

Code :
  1. int set_bit(int val, int pos) {
  2.      if (val < pow(2,pos)
  3.          val += pow(2,pos);
  4. }


 
Qu'en pensez vous ?


Horrible !
 
En fait horriblement lent... Les bitwise operators sont là pour ça.
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1247227
meumeul
Stay Heavy
Posté le 16-11-2005 à 22:28:37  profilanswer
 

Emmanuel Delahaye a écrit :

Horrible !
 
En fait horriblement lent... Les bitwise operators sont là pour ça.


 
en plus j'ai inversé les params de mes appels a pow(...,...)

n°1247273
matafan
Posté le 17-11-2005 à 01:10:13  profilanswer
 

Code :
  1. #define SET_BIT(_lval, _bit) ((_lval) |= (1<<(_bit)))


Ou un truc dans le genre. Je te laisse faire l'autre macro.

n°1247438
Sve@r
Posté le 17-11-2005 à 11:13:42  profilanswer
 

meumeul a écrit :

j'ai trouvé ca sur le site koders

Code :
  1. #define SET_BIT(flag,bit) ((flag) |= (bit))
  2. #define REMOVE_BIT(flag,bit) ((flag) &= ~(bit))


mais je ne sais pas comment l'utiliser ...


 
Les opérateurs "&", "|" , "^" et "~" permettent de faire un "ET", un "OU", un "NOT" et un "XOR" sur une ou deux valeurs... mais "bit à bit"
 
Exemple:
val1 = 10 (1010 binaire)
val2 = 12 (1100 binaire)
 
val1 | val2 = 1110 binaire soit 14
val1 & val2 = 1000 binaire soit 8
val1 ^ val2 = 0110 binaire soit 6
~val1 = 0101 binaire soit 5
~val2 = 0011 binaire soit 3
 
Partant de là, tu peux combiner ces opérateurs à souhait pour mettre le bit que tu veux à 1, à 0, vérifier s'il est à 1 ou pas
Exemple
#define BIT1     (0x01)
#define BIT2     (0x02)
#define BIT3     (0x04)
#define BIT4     (0x08)
#define BIT5     (0x10)
#define BIT6     (0x20)
#define BIT7     (0x40)
#define BIT8     (0x80)
 
int flag=0;
 
Je veux mettre le 4° bit du flag (en partant de la droite) à 1 => flag=flag | BIT4
Je veux mettre le 5° bit du flag à 0 => flag=flag & (~BIT5)
Je veux permuter le 6° bit du flag => flag=flag ^ BIT6
Je veux vérifier si le 7° bit du flag vaut 1 => "if (flag & BIT7)" ou bien "if ((flag & BIT7) == BIT7)"
 
Une fois que t'as compris le principe, t'as plus qu'à écrire des macro plus parlantes telles que "FLAG_ON", "FLAG_OFF" etc...

Message cité 1 fois
Message édité par Sve@r le 17-11-2005 à 11:18:05

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1247897
meumeul
Stay Heavy
Posté le 17-11-2005 à 18:46:32  profilanswer
 

Sve@r a écrit :

Les opérateurs "&", "|" , "^" et "~" permettent de faire un "ET", un "OU", un "NOT" et un "XOR" sur une ou deux valeurs... mais "bit à bit"
 
Exemple:
val1 = 10 (1010 binaire)
val2 = 12 (1100 binaire)
 
val1 | val2 = 1110 binaire soit 14
val1 & val2 = 1000 binaire soit 8
val1 ^ val2 = 0110 binaire soit 6
~val1 = 0101 binaire soit 5
~val2 = 0011 binaire soit 3
 
Partant de là, tu peux combiner ces opérateurs à souhait pour mettre le bit que tu veux à 1, à 0, vérifier s'il est à 1 ou pas
Exemple
#define BIT1     (0x01)
#define BIT2     (0x02)
#define BIT3     (0x04)
#define BIT4     (0x08)
#define BIT5     (0x10)
#define BIT6     (0x20)
#define BIT7     (0x40)
#define BIT8     (0x80)
 
int flag=0;
 
Je veux mettre le 4° bit du flag (en partant de la droite) à 1 => flag=flag | BIT4
Je veux mettre le 5° bit du flag à 0 => flag=flag & (~BIT5)
Je veux permuter le 6° bit du flag => flag=flag ^ BIT6
Je veux vérifier si le 7° bit du flag vaut 1 => "if (flag & BIT7)" ou bien "if ((flag & BIT7) == BIT7)"
 
Une fois que t'as compris le principe, t'as plus qu'à écrire des macro plus parlantes telles que "FLAG_ON", "FLAG_OFF" etc...


 
 
 
super, merci a tous pour votre aide.
Tant qu'on est dans les histoires de bits, j'ai un autre probleme que je ne saisi pas :

Code :
  1. long int ttt = (long int) pow(2,30);
  2.       printf("test %d\n", ttt);


Le code marche et affiche la bonne valeur.
mais

Code :
  1. long int ttt = (long int) pow(2,31);
  2.       printf("test %d\n", ttt);


retourne un nombre negatif...
 
Je pensais que ca n'étais le cas que pour  pow(2,32) !
Alors je me suis dit que le bit de poids fort était reservé pour le signe.
Donc j'ai déclaré mes "long int" en "unsigned long int"
mais pow(2,31) est toujours négatif ....
 
Et j'ai vraiment besoin quil soit positif. Je ne vois pas pourquoi il ne l'est pas :S
 
Une idée ?? Merci ...

mood
Publicité
Posté le 17-11-2005 à 18:46:32  profilanswer
 

n°1247898
Emmanuel D​elahaye
C is a sharp tool
Posté le 17-11-2005 à 18:54:26  profilanswer
 

meumeul a écrit :

Et j'ai vraiment besoin quil soit positif. Je ne vois pas pourquoi il ne l'est pas


Dans ce cas, utiliser des non signés et le bon formatteur.


   unsigned long ttt = pow(2,31);
   printf("test %lu\n", ttt);


Message édité par Emmanuel Delahaye le 17-11-2005 à 18:56:54

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1247899
meumeul
Stay Heavy
Posté le 17-11-2005 à 18:57:10  profilanswer
 

Génial ...  J'ai un peu honte :( mais je débute encore en C.
Il était bien nécessaire de le mettre unsigned alors ...
 
Merci !

n°1247948
el muchach​o
Comfortably Numb
Posté le 17-11-2005 à 20:51:51  profilanswer
 

Juste un truc, suite à l'une de tes remarques : il faut faire très attention si tu comptes utiliser des nombres de l'ordre de grandeur de la valeur max autorisée par un type, parce que le C ne te prévient pas s'il dépasse la capacité du type. Tu peux très bien avoir un résultat complètement faux sans que tu ne t'en rendes compte, ou alors trop tard. Donc il faut absolument s'assurer que les manips/calculs n'engendreront pas de dépassement, et là, il n'y a pas d'autre technique pour éviter le bug que de bien vérifier les ordres de grandeur utilisés dans les calculs.


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
n°1248139
Sve@r
Posté le 18-11-2005 à 10:03:06  profilanswer
 

meumeul a écrit :

Génial ...  J'ai un peu honte :( mais je débute encore en C.
Il était bien nécessaire de le mettre unsigned alors ...
 
Merci !


Il y a le problème de la déclaration du type qui te permet de faire des calculs corrects... et celui du format d'affichage de "printf" qui demande à "printf" de considérer la valeur comme signée ou pas.
 
Exemple:
short a=0x8000       => a vaut     1000 0000 0000 0000
long b=a                 => b vaudra 1111 1111 1111 1111 1000 0000 0000 0000
Etant donné que tu travailles en "signé", et que le bit de signe vaut "1", celui-ci est étendu sur le long pour que la valeur soit la même entre "a" et "b"
 
Maintenant
unsigned short a=0x8000       => a vaut 1000 0000 0000 0000
long b=a                             => b vaudra 0000 0000 0000 0000 1000 0000 0000 0000
Comme "a" est non signé, le "1" ne signifie plus "nombre négatif" mais "valeur" et n'a pas à être étendu sur le "long"
 
Maitenant, quand tu affiches "a" ou "b" avec "printf", c'est à toi de spécifier si la valeur que tu lui passes doit être considérée comme signée ou pas... parce que "printf" ne connait pas le type de "a" ou "b" d'où le :
- %u pour un int qu'on veut afficher en non signé
- %d pour un int qu'on veut afficher en signé
- %hu pour un short qu'on veut afficher en non signé
- %hd pour un short qu'on veut afficher en signé
- %lu pour un long qu'on veut afficher en non signé
- %ld pour un long qu'on veut afficher en signé
 
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1248653
slash33
Posté le 18-11-2005 à 18:00:59  profilanswer
 

meumeul a écrit :

Génial ...  J'ai un peu honte :( mais je débute encore en C.
Il était bien nécessaire de le mettre unsigned alors ...
 
Merci !


C'est pas lié au C c'est de la logique combinatoire. Il ne faut pas tout confondre.

n°1249729
db__
spécialiste de l'à peu près
Posté le 21-11-2005 à 12:31:15  profilanswer
 

Bonjour
soit le programme suivant :
 
#include <stdio.h>
 
int main (int argc, char *argv[])
{
        short           a;
        unsigned short  b;
        long            c;
        long            d;
 
        a = 0x8000;
        b = 0x8000;
        c = a;
        d = b;
        printf ("short : %x, long : %x\n", a, c);
        printf ("unsigned short : %x, long : %x\n", b, d);
}
 
"sanssigne.c" [Nouveau] 21L, 375C écrit(s)
fronsac:13> gcc -o sanssigne sanssigne.c
fronsac:14> sanssigne
short : ffff8000, long : ffff8000
unsigned short : 8000, long : 8000
 
Au vu du résultat produit, il semblerait que gcc décide de coder les short sur 32 bits.
Si un spécialiste de la norme pouvait éclairer ce comportement, nous en serions ravi !

n°1249746
Emmanuel D​elahaye
C is a sharp tool
Posté le 21-11-2005 à 12:54:07  profilanswer
 

db__ a écrit :

Bonjour
soit le programme suivant :

fronsac:14> sanssigne
short : ffff8000, long : ffff8000
unsigned short : 8000, long : 8000


Au vu du résultat produit, il semblerait que gcc décide de coder les short sur 32 bits.
Si un spécialiste de la norme pouvait éclairer ce comportement, nous en serions ravi !


 
Comment le sais tu ? Tu passes un short à une fonction variadic. Il est converti en int. Comme il est signé, le signe est étendu parce que ton implémentation utilisé la représentation 'complément à deux' pour les nombres négatifs.
 
de plus, tu utilises le formatteur "%" qui attentd un int non signé. Le résultat est donc indéterminé... Mon compilateur m'a prévenu :  


../main.c: In function `main_':
../main.c:15: warning: unsigned int format, long int arg (arg 3)
../main.c:16: warning: unsigned int format, long int arg (arg 3)


Ce code est maintenant conforme à la norme


#include <stdio.h>
 
int main (void)
{
   short a;
   unsigned short b;
   long c;
   long d;
 
   a = 0x8000;
   b = 0x8000;
   c = a;
   d = b;
   printf ("short : %hx, long : %lx\n", (unsigned short) a, c);
   printf ("unsigned short : %hx, long : %lx\n", (unsigned short) b, d);
 
   return 0;
}


et le résultat est conforme aux attentes.


short : 8000, long : ffff8000
unsigned short : 8000, long : 8000

Message cité 1 fois
Message édité par Emmanuel Delahaye le 21-11-2005 à 15:43:01

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1249920
Sve@r
Posté le 21-11-2005 à 15:07:59  profilanswer
 

Emmanuel Delahaye a écrit :

Comment le sais tu ? Tu passes un short à une fonction variadic. Il est converti en int. Comme il est signé, le signé est étendu parce que ton implémentation utilisé la représentation 'complément à deux' pour les nombres négatifs.
 
de plus, tu utilises le formatteur "%" qui attentd un int non signé. Le résultat est donc indéterminé...


 
Héhé... tout le problème de l'indépendance qu'il y a entre "type" et "affichage"...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1250654
db__
spécialiste de l'à peu près
Posté le 22-11-2005 à 12:29:21  profilanswer
 

J'ai vérifié par une sortie assembleur de la compilation qu'il code effectivement bien les short en 16 bits mais qu'il envoie sur la pile uniquement des 32 bits avec ou pas extension de signe suivant le cas. printf ne prend donc que des arguments de 32 bits.
Je savais qu'il y avait indépendance entre variable et affichage mais je n'imaginais pas qu'il y ait changement de taille de variable  pour la représenter.
merci pour ces informations.

n°1250688
Emmanuel D​elahaye
C is a sharp tool
Posté le 22-11-2005 à 13:17:15  profilanswer
 

db__ a écrit :

J'ai vérifié par une sortie assembleur de la compilation <...>


Chaque implémentation fait ce qu'elle veux. L'implémentation n'est pas définie par le langage. Ce que définit le langage ce sont les comportements et les interfaces.
 
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1250936
minimoke
beep beep
Posté le 22-11-2005 à 18:45:39  profilanswer
 

pour quelque chose de portable est ce qu'il existe une structure byte qui a 1 octet d'info exactement.

n°1250941
minimoke
beep beep
Posté le 22-11-2005 à 18:53:46  profilanswer
 

lol :-)

n°1250961
Emmanuel D​elahaye
C is a sharp tool
Posté le 22-11-2005 à 19:22:18  profilanswer
 

minimoke a écrit :

pour quelque chose de portable est ce qu'il existe une structure byte qui a 1 octet d'info exactement.


Un unsigned char. fait par définition exactement un byte.
 
Par contre, la notion de "exactement un octet" n'existe pas en C de façon portable. Un char fait au moins 8 bits. Il peut en faire plus.
 
 
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1254651
meumeul
Stay Heavy
Posté le 28-11-2005 à 14:00:18  profilanswer
 

ok merci , tant quon est dans les bits, j'ai une petite derniere question.
Je prends ces unsigned long int pour représenter des ensembles de 1 à 32 inclus en fait.  
Pour les opération ensemblistes de base tel que l'union l'intersection et le complément, pas de problème, j'utilise | & et ~ .  
Mais pour la 'différence' de deux ensembles, je trouve pas d'autres moyen que de regarder chacun des 32 bits deux a deux des deux opérandes de la différence. Y'a t il un moyen avec une combinaison d'opérateurs bits a bits ? Je vois pas du tout ... j'ai tenté des trucs avec un complément de l'intersection mais c'est pas du tout ca lol

n°1254657
blackgodde​ss
vive le troll !
Posté le 28-11-2005 à 14:16:00  profilanswer
 

^ (ou exclusif) ?
dans le résultat les bits ne correspondant pas seront à 1, ceux correspondant à 0


---------------
-( BlackGoddess )-
n°1254658
meumeul
Stay Heavy
Posté le 28-11-2005 à 14:18:44  profilanswer
 

on  m'a proposé ca ailleurs :  
a - b = a & (~ b)
 
je vais le tester

n°1254662
meumeul
Stay Heavy
Posté le 28-11-2005 à 14:22:18  profilanswer
 

le ^ marche pas : (la condition n'est pas suffisante)
 
{1,2} diff {1,4} donne { 2 , 4 } au lieu de {2}
 

n°1254767
matafan
Posté le 28-11-2005 à 16:23:09  profilanswer
 

meumeul a écrit :

on  m'a proposé ca ailleurs :  
a - b = a & (~ b)


Ça marche.

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  positionner un bit sur un int

 

Sujets relatifs
Juste un texte à positionner... Juste...se positionner à un endroit dans un texte
CSS : positionner une image ou un bloc en bas d'un autre blocComment positionner relativements des images survolées ?
Positionner une image CSSPositionner horizontalement trois div
Comment positionner des bloc <div> </div>Se positionner dans un recordset
Positionner un commentaireEst-il possible de positionner automatiquement le pointeur de souris ?
Plus de sujets relatifs à : positionner un bit sur un int


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)