Home
Home

--- Soumis par Terry Kreft---

Bits et masques

Les opérations sur les bits nous permettent d'emmagasiner plusieurs informations dans une valeur, en VBA. Le concept est tr`s voisin de celui utilisé en Win32 API, où un argument drapeau (flag) peut représenter un ensemble de conditions.

4 bits, un demi-octet, peuvent représenter jusqu'à  16 nombres (j'ignore, pour l'instant, la possibilité d'utiliser un signe)

En effet, il y a 16 arrangements possibles, de zéros et de uns, soit:

0000, 0001, 0010, 0011,
0100, 0101, 0110, 0111,
1000, 1001, 1010, 1011,
1100, 1101, 1110, 1111

Si on considère qu'il s'agit là de nombres entiers positifs, en base deux, leur conversion décimale est simplement:-

0,  1,  2,  3,
4,  5,  6,  7,
8,  9, 10, 11,
12, 13, 14, 15

Si on ne retient que les combinaisons qui ne possèdent qu'un seul un, et trois zéros, on trouve:

0001  (= 1)
0010  (= 2)
0100 (= 4)
1000 (= 8)

On peut s'amuser à additionner ces nombres entre eux pour générer tous les autres nombres, comme par exemple

    1 + 2 = 3      (0001 + 0010 = 0011)
    1 + 4 = 5      (0001 + 0100 = 0101)
    4 + 8 = 12    (0100 + 1000 = 1100)
et ainsi de suite...
 
    1 + 2 + 4 + 8 = 15 ( 0001 + 0010 + 0100 + 1000 = 1111)

Un masque, par ailleurs, implique l'utilisation de l'opérateur logique AND (ET) pour déterminer quels sont les bits qui possèdent la valeur 1. Ainsi, si vous désirez examiner quels sont les bits de la valeur 7 qui sont à 1, vous pourriez utiliser une expression comme:

?(7 AND 4) = 4

qui retourne vrai parce que le bit #2 ( le troisième, de la droite vers la gauche) dans le nombre 7 (0111) est bel et bien un 1.

Avec plus de détails, considérer que chaque bit, individuellement, du premier nombre est comparé à son homologue, son correspondant, du second nombre et s'ils sont tous deux à 1, alors le résultat est également 1, zéro dans les autres cas. Avec plus de détails:

    7  = 0111
    4  = 0100
 
0th bit comparaison de 1 And 0 = 0
1st bit comparaison de 1 And 0 = 0
2nd bit comparaison de 1 And 1 = 1
3rd bit comparaison de 1 And 0 = 0

qui, remis en écriture horizontale, nous laisse

0100 = 4

et ainsi donc, la comparaison binaire:  7 And 4  résulte en la valeur 4.

?(7 AND 4) = 4

nous retourne donc Vrai.

Prenons maintenant un exemple d'utilisation de masque pour emmagasiner un résultat.  Imaginons une agence d'emploi qui emmagasine quatre propriétés binaires, soit le sexe, si la personne est employée, si elle possède un permis de conduire un véhicule et si elle recherche un emploi à temps plein.

On peut alors assigner les propriétés comme suit: 

    Const IsFemale = 1
    Const IsEmployed = 2
    Const CanDrive = 4
    Const FullTime = 8

Lorsqu'un nouveau candidat fait application, il s'agit de demander les questions pertinentes et ainsi, de calculer le nombre résultant.

Ainsi, avec Fred qui est un homme, actuellement employé, ne peut conduire de véhicule et cherche un emploi à temps plein, on aurait, ne considérant que les réponses positives:

IsEmployed + FullTime (= 2 + 8 = 10)

On peut alors assigner le nombre 10 dans un champ d'une table (disons AppProps ) et par la suite, on pourra manipuler cette information avec des masques.

Pour repérer qui est actuellement employé, avec l'enregistrement de Fred, nous aurions

?(AppProps and FullTime) = FullTime

qui retournera Vrai (substituer AppProps par 10, pour vérification), montrant que Fred est actuellement employé. Si l'emploi requiert une femme, avec Fred

?(AppProps AND IsFemale) = IsFemale

le résultat sera Faux et ainsi, Fred n'est pas un candidat valide pour cette offre d'emploi.

On peut évidemment faire le tout en une seule opération, à savoir

?(AppProps And (IsFemale Or FullTime)) = (IsFemale Or FullTime) 

qui retourne Faux, évidemment, dans notre cas.

Avec Jeanne, une femme actuellement employée qui recherche un emploi à temps plein, mais sans permis de conduire, nous obtenons 11 pour la valeur à emmagasiner dans le champ AppProps:

(IsEmployed + FullTime + IsFemale = 2 + 8 + 1 = 11)

et également, par exemple, nous obtenons

?(AppProps and FullTime) = FullTime

retournant Vrai

?(AppProps AND IsFemale) = IsFemale

retournant Vrai et aussi

?(AppProps And (IsFemale Or FullTime)) = (IsFemale Or FullTime)

retournant Vrai. Donc, ici, Jeanne satisfait les exigences de l'emploi.

Voici un peu de code illustrant le tout:

'*************  Code Start  ********************
Const IsFemale = 1
Const IsEmployed = 2
Const CanDrive = 4
Const FullTime = 8
 
Function TestBitMasks()
  Dim FredProps As Byte
  Dim JoanProps As Byte
 
  FredProps = IsEmployed + FullTime
  Debug.Print "Fred is FullTime?: "; _
    (FredProps And FullTime) = FullTime
  Debug.Print "Fred is Female?: "; _
    (FredProps And IsFemale) = IsFemale
  Debug.Print "Fred is FullTime and Female?: "; _
    (FredProps And (IsFemale Or FullTime)) = (IsFemale Or FullTime)
 
  JoanProps = IsEmployed + FullTime + IsFemale
  Debug.Print "Joan is FullTime?: "; _
    (JoanProps And FullTime) = FullTime
  Debug.Print "Joan is Female?: "; _
    (JoanProps And IsFemale) = IsFemale
  Debug.Print "Joan is FullTime and Female?: "; _
    (JoanProps And (IsFemale Or FullTime)) = (IsFemale Or FullTime)
 
End Function
'*************  Code End  ********************