Comment lire un bit à droit à gauche à la xième position dans un octet ?

Résolu
AhmedBoudali Messages postés 14 Date d'inscription mardi 24 octobre 2000 Statut Membre Dernière intervention 13 décembre 2005 - 11 déc. 2005 à 12:37
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 - 13 déc. 2005 à 21:31
Bonjour ,

Je voudrais mettre en oeuvre la compression de Huffman mais je ne trouve pas la fonction tordue qui lit un bit. Quelqu'un a découvert ou rencontré cette solution ?

Grand Merci.

AhmedBoudali

12 réponses

jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
11 déc. 2005 à 15:32
function extractbit(valeur:byte;numbit:integer):boolean;

var vrai:integer;

begin

vrai:= valeur and 1 shl numbit ; // on decale 1 de numbit vers la gauche et on fait un et logique avec la valeur à tester

if vrai<>0 then result: =true else result := false; //renvoie vrai si le bit N° numbit est à 1 faux dans le cas contraire

end;

@+

jlen
3
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
11 déc. 2005 à 13:35
salut

utilises l'operateur logique AND en appliquant un masque sur le bit que tu veux lire

exemple:

a:=8;(bit 4 à 1); hex 00001000

masque:= 8;

a and masque-->

00001000

00001000=

00001000--->vrai

if (a and masque) then vrai

masque:=00000100; (4)

00001000

00000100

00000000-->faux

a and 4=0 faux

tu répètes l'opération pour chaque bit

@+

jlen
0
AhmedBoudali Messages postés 14 Date d'inscription mardi 24 octobre 2000 Statut Membre Dernière intervention 13 décembre 2005
11 déc. 2005 à 20:01
Là, je dois dire merci. C'est tout à fait ça.

A l'occasion, une petite réflexion ou un tutoriel sur comment lire/écrire un bit serait un apport intéressant.

AhmedBoudali
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
11 déc. 2005 à 20:42
j'essayerai d'y penser

petite explication

un and logique fait une comparaison bit à bit entre les 2
membres de l'équation . Pour chaque bit le résultat est 1 si les 2 bits
testés sont égaux à 1.

pour tester un bit particulier X d'un mot V de N bit on utilise un
masque ou l'on met à 1 le Xiéme bit du masque et tous les autres à 0 .
Quand on fait un et logique (and) entre ce mot et le masque tous
les bits à 0 du masque donneront 0 comme résultat si le Xiiéme bit du
mot V égal à 0 nous avons 0 et 1 (du masque) donc le resultat final est
égal à 0 pour tout le mot; maintenant si le Xiiéme bit du mot V eégal à
1 le et logique entre ce bit et celui du masque donne 1 et donc le
résultat final est différent de zéro.

Pour mettre le Xieme bit du masque à 1 j'ai utilisé un décalage à gauche.

Au départ je mets la valeur du masque à 1 (bit 0= 1) puis je décale vers
la gauche ce bit à chaque décalage le bit de droite est mis à 0

cela donne au départ (pour un mot de 8 bits mais c'est valable
également pour un integer de 32 bits)

00000001

au premier décalage à gauche 00000010

au second decalage à gauche 00000100

et ainsi de suite.

noter également que le décalage à gauche est un moyen efficace de multiplier par 2 un nombre au depart

0000 0001 = 1 (0 decalage)

0000 0010 = 2 au 1er décalage

0000 0100 = 4 au 2eme

0000 1000 = 8 au 3eme

....

ceci est valable quelque soit le nombre dans la limite du domaine de validité de l'entier

et attention quand on arrive à la limite

0111 1111 1111 1111 (smallint= 32767) donne

1111 1111 1111 1110 soit ...-2 ( le bit de poids fort est le bit de signe)

par contre la même opération sur un word donnera 65534.

En relisant mon code on aurait pu écrire directement:

function extractbit(valeur:byte;numbit:integer):boolean;

begin

if ( valeur and 1 shl numbit)<> 0 then result: =true else result := false; ; // on decale 1 de numbit vers la gauche et on fait un et logique avec la valeur à tester

renvoie vrai si le bit N° numbit est à 1 faux dans le cas contraire

end;

et ainsi éviter une variable intermédiaire.

@+

jlen
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
11 déc. 2005 à 20:55
en complément on peut également un bit particulier dans un mot celà
nécessite 2 méthodes différente suivant que l'on veut mettre à 1 ou
mettre à 0 ce bit

pour mettre à 1 on prépare le masque comme précédemment et on fait un ou logique (or)

un ou logique met à 1 tous les bits à 1 du mot ou du masque soit:

V:= V or masque

pour mettre à 0 un bit il faut faire un et logique avec un 0 dans le
masque. pour préparer le masque on déclare un variable entiere non
signée par exemple

var masque:byte;// mot de 8 bits non signé

masque: =254; //tous les bits à 1 sauf le bit 0;

masque:=masque shl(numbit);// on décale le 0 de numbit

V:=V and masque;

@+

jlen
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
12 déc. 2005 à 08:04
un erreur c'est glissée dans mon code pour reseter un bit il faut préparer le masque comme ceci:

masque:= 255-(1 shl numbit);

V: =V and masque;

je m'explique:

1 shl numbit on decale 1 du N° du bit à mettre à 0 ATTENTION le bit de poids faible est le bit 0.

ensuite on complemenet à 2 (je ne me souviens plus de l'opérateur correspepondant en DELPHI équivalent à ~
en C si quelqu'un à la réponse...)

par exemple pour mettre à 0 le bit N°2:

1 shl 2:= 4 (100 en binaire)

masque:= 255-4-->251 (1111 1011 en binaire)

@+

jlen
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
12 déc. 2005 à 11:27
grosse fatigue :

pour obtenir le complément à 2 il suffit de faire un NOT ce qui donne

masque:= not(1 shl numbit);
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
12 déc. 2005 à 11:38
seul probleme, après vérification, c'est que le compilateur n'en veut pas directement il faut donc écrire:

masque:= 1 shl numbit;

masque: =not masque;

OUF on va y arriver. un peu compliqué DELPHI pour un malheureux complément à 2!!!
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
13 déc. 2005 à 20:33
function extractbit(valeur:byte;numbit:integer):boolean;

var vrai:integer;

begin

vrai:= valeur and 1 shl numbit ; // on decale 1 de numbit vers la gauche et on fait un et logique avec la valeur à tester

if vrai<>0 then result: =true else result := false; //renvoie vrai si le bit N° numbit est à 1 faux dans le cas contraire

end ;



On aurait pu raccourcir comme ceci:

function extractbit(valeur:byte;numbit:integer):boolean;

begin

result: =(valeur and 1 shl numbit)<>0;

end;



Mais bon la je chipote un peu...
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
13 déc. 2005 à 21:14
-->CptPingu, je te pardonne de n'avoir pas lu tous les post (c'est
vrai qu'ils sont nombreux) mais j'avais corrigé un peu plus loin (enfin
presque):

function extractbit(valeur:byte;numbit:integer):boolean;

begin if ( valeur and 1 shl numbit)<> 0 then result:true else result : false; ; // on decale 1 de numbit vers la gauche et on fait un et logique avec la valeur à tester

renvoie vrai si le bit N° numbit est à 1 faux dans le cas contraire

end;

l'avantage didactique de la premiere version c'est d'être plus facilement comprehensible.

@+

jlen
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
13 déc. 2005 à 21:19
A en effet je n'ai pas tout lu désoler (je suis passé directement sur
les derniers posts qui me paraissait être l'aboutissement des premiers).

Quand à a la maniere d'écrire les booléen, c'est vrai que c'est un question de gout...
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
13 déc. 2005 à 21:31
ça tient au fait que je pratique aussi le C et l'assembleur ( ou
l'on teste soit la carry soit le zero que l'on affecte ensuite au
resultat ) et qu'il vaut mieux être prudent avec eux.

les derniers post ne sont pas l'aboutissement mais une tentative
d'expliquer la manipulation de bits (mais il vaudrait
mieux que j'évite de programmer avant et après une teuf!!
ça limiterait les posts inutiles
0
Rejoignez-nous