Champs de bits / Variables de taille n bits

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Naheulf
Messages : 191
Inscription : dim. 10/mars/2013 22:22
Localisation : France

Champs de bits / Variables de taille n bits

Message par Naheulf »

Bonjour à tous et à toutes,

Est-ce que quelqu’un(e) sait comment déclarer une structure avec des champs qui ne sont pas des multiples d’un octet ?

Je voudrais arriver à faire l’équivalent du code C suivant :

Code : Tout sélectionner

struct CompressedChunkHeader{
     unsigned size:12;
     unsigned signature:3;
     unsigned flag:1;
     unsigned reserved:16:
};
L'idéal serait bien évidement de pouvoir accéder aux valeurs avec un simple

Code : Tout sélectionner

Structure CompressedChunkHeader [Align 0.125]
    size.???
    signature.???
    flag.???
    reserved.w
EndStructure

maStructure.CompressedChunkHeader
maStructure\size = 9
;some code
If maStructure\signature <> sommeDeControle
    ; erreur
EndIf
D'après ce que j'ai vu il faut nécessairement passer par les opérateurs binaires. "&", "|", "<<" et ">>".
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Champs de bits / Variables de taille n bits

Message par nico »

Oui, il faut passer par les opérateurs binaires. Il est possible aussi de le faire en passant par des chaines de caractères.

Tiens, je te fais un exemple ici:
Dans cet exemple, je prend les valeurs en commençant par le bit de poids fort vers le bit de poids faible, on peut faire l'inverse mais c'est pas forcément nécessaire et utile de rajouter du code en plus dans notre cas.
[Edit] modification du code, travaille avec 8, 16, 32 ou 64 bit

Code : Tout sélectionner

Structure CompressedChunkHeader
    ;  la valeur ChunkHeader qui nous intéresse qui sera répartie dans les variables qui suivent après traitement.
    ChunkHeader.l
    size.l
    signature.l
    flag.l
    reserved.l
EndStructure
 
Procedure.q bit(Valeur.q, PositionDepart.l, Longueur.l, nbBit.l)
    Protected Valeur$
    
    Valeur$ = Bin(Valeur, #PB_Quad)
    Valeur$ = RSet(Valeur$, nbBit, "0")
    Debug Valeur$
    Valeur$ = Mid(Valeur$, PositionDepart, Longueur) 
    Debug Valeur$
    Valeur = Val("%" + Valeur$)
    
    ProcedureReturn Valeur
EndProcedure


test.CompressedChunkHeader\ChunkHeader = %00101111000011110101111100001111
                                              
test\size =  bit(test\ChunkHeader, 1, 12, 32)
Debug test\size

test\signature =  bit(test\ChunkHeader, 13, 3, 32)
Debug test\signature

test\flag =  bit(test\ChunkHeader, 16, 1, 32)
Debug test\flag

test\reserved = bit(test\ChunkHeader, 17, 16, 32)
Debug test\reserved
Dernière modification par nico le dim. 29/avr./2018 17:10, modifié 2 fois.
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Champs de bits / Variables de taille n bits

Message par Fig »

A ma connaissance, en Pb il est nativement impossible d'accéder à des bits, encore moins d'utiliser une structure non multiple de l'octet.
Il faut utiliser les opérateurs binaires et cela complique légèrement le code.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
GallyHC
Messages : 1703
Inscription : lun. 17/déc./2007 12:44

Re: Champs de bits / Variables de taille n bits

Message par GallyHC »

Bonjour,

Je penses juste que pour la signature, on peut faire "signature.s{3}", après j'avoue que je ne sais pas.

Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Champs de bits / Variables de taille n bits

Message par nico »

Mais pourquoi intervenir pour simplement répéter ce qui est déjà écrit précédemment?
Avatar de l’utilisateur
GallyHC
Messages : 1703
Inscription : lun. 17/déc./2007 12:44

Re: Champs de bits / Variables de taille n bits

Message par GallyHC »

Bonjour,
nico a écrit :Mais pourquoi intervenir pour simplement répéter ce qui est déjà écrit précédemment?
C'est pour qui cette phrase?

GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Champs de bits / Variables de taille n bits

Message par Fig »

nico a écrit :Mais pourquoi intervenir pour simplement répéter ce qui est déjà écrit précédemment?
Si ça me concerne, tu as posté alors que j'écrivais moi aussi, tout simplement.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Champs de bits / Variables de taille n bits

Message par nico »

Ok, déolé.
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Champs de bits / Variables de taille n bits

Message par Ollivier »

Moi, j'ai une technique de psychopathe : chaque bit est un entier signé de 64 bits de type quad. Tu extrais l'info, tu lis et modifies l'info, puis tu la recomprime en bits.

Code : Tout sélectionner

Structure Psychostruc
    Size.I[12]
    Signature.I[3]
    Flag.I
    Reserved.I[16]
EndStructure
Une fois que c'est modifié, plié... Hop, recompression ICI
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: Champs de bits / Variables de taille n bits

Message par G-Rom »

ton code en C correspond a cela en PB :

Code : Tout sélectionner

Structure CompressedChunkHeader
    reserved.l
EndStructure
Il faut que tu joue avec les bits pour accéder aux éléments, attention a la capacité des champs, 12 bits , c'est moins qu'un word, environ +/- 2047
soit en gros :

Code : Tout sélectionner

Structure CompressedChunkHeader
    reserved.l
EndStructure


Macro setSize(struct, size)
 struct\reserved = struct\reserved &FFF | (size<<19)  
EndMacro

Macro getSize(struct)
  struct\reserved >> 19 & $FFF
EndMacro

Macro setSignature(struct, size)
  struct\reserved = struct\reserved | (size<<15)
EndMacro

Macro getSignature(struct)
  struct\reserved >> 15 & $F
EndMacro

Macro setFlag(struct, bit)
  If bit=1
    struct\reserved  | (1<<14) 
  Else
    struct\reserved & (254 << 14)
  EndIf  
EndMacro

Macro getFlag(struct)
  Struct\reserved >> 14 & $1
EndMacro


A.CompressedChunkHeader
A\reserved = 0
setSize(A,245)
setSignature(A,15)
setFlag(A,1)

Debug RSet(Bin(A\reserved),32,"0")

 Debug getSize(A)
 Debug getSignature(A)
 Debug getFlag(A)
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Champs de bits / Variables de taille n bits

Message par Ollivier »

Tiens, ça m'étonne que ce soit en little endian les champs de bits en C.

Si c'est le cas, mon code de compression de quads booléens en bits est à mettre au placard !
G-Rom
Messages : 3626
Inscription : dim. 10/janv./2010 5:29

Re: Champs de bits / Variables de taille n bits

Message par G-Rom »

J'ai pas pris en compte l'endianess, tu peu changer mon code pour changé les bits dans l'ordre qui t'arrange.
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Champs de bits / Variables de taille n bits

Message par Ollivier »

J'ai essayé de trouver une soluce à la fois proche de la syntaxe actuelle (structure+lecture+écriture) en maintenant la performance : impossible.

La syntaxe bloque. Et la structuration (créer une structure avec des champs variable en fonction des arguments d'une macro) bloque aussi.

Le seul petit truc que j'ai "réussi" à pondre, c'est le masque d'un champ :

Code : Tout sélectionner

Macro BitMask(BitStart, BitLength)
   (((1 << BitLength) - 1) << BitStart)
EndMacro
C'est en big endian à base 0 pour BitStart et en bits pour BitLength.

Le problème, c'est que c'est quasiment impossible d'obtenir les deux arguments BitStart et BitLength sous forme de constante pré-calculée à partir d'une liste de directive de type

Code : Tout sélectionner

bStruc(maStruc,
Champs1,3,
Champs2,2,
DernierChamps,11)
J'arrive à obtenir des suites polynomiales avec les macros. Par exemple

Code : Tout sélectionner

Debug myMacro
Debug myMacro
Debug myMacro
Debug myMacro
qui donne

Code : Tout sélectionner

1
3
6
10
mais je n'arrive pas à faire un calcul de type "oignon" avec les macros.
De ce type:

Code : Tout sélectionner

0
0+3
0+3+2
0+3+2+11
sachant que si toutes ces valeurs sont des constantes ou des arguments de macros, elles peuvent être stockées dans des constantes et donc être précalculées.
Avatar de l’utilisateur
Naheulf
Messages : 191
Inscription : dim. 10/mars/2013 22:22
Localisation : France

Re: Champs de bits / Variables de taille n bits

Message par Naheulf »

Merci pour toutes vos réponses.

Au moins c'est clair : Il n'y a plus qu'à se faire sa propre tambouille pour accéder aux bits.

Merci à tous
Répondre