Carte du site
 Remerciements
 Netiquette
 Bugs
 Tables
 Requêtes
 Formulaires
 États (rapports)
 Modules
 APIs
 Chaînes
 Date/Time
 Général
 Ressources
 Téléchargeables

 Termes d'usage

General: Bits et masques

Author(s)
Terry Kreft

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) car chaque bit peut prendre la valeur 0 ou la valeur 1. En fait, voici ces 16 possibilités.

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)

Maintenant, l'utilisation de masque implique l'utilisation de l'opérateur AND, ce qui nous permet de spécifier quels bits peuvent être visibles, ou sélectionnés. En effet, si le bit "i" est 1e bit correspondant du second argument sera choisi, alors que si le bit "i" est zéro, un zéro sera dans le résultat, indépendamment du bit correspondant du second arguement. Prenons un exemple pour illustrer

   ? ( 7 AND 10)  
Retourne 2 car si on décompose les arguments en bits, on trouve (0111) AND (1010). Si on considère que le masque est le premier argument (on obtient le même résultat en inversant les rôles), il signifie donc de ne pas considérer le premier bit du second argument, prenant 0. Ensuite, il dit de prendre le second bit du second argument, de même que le troisième et le quatrième. On se retrouve donc avec quatre bits, 0 0 1 0, soit, le nombre 2. On peut également voir le tout comme si chaque bit serait soumis à l'opérateur AND avec son correspondant.
   7 = 0 1 0 0
 10 = 1 0 1 0
  	
Premiers bits:  0 AND 1  retourne 0
bits en position 2:  1 AND 0  retourne 0
bits en position 3:  1 AND 1  retourne 1
bits en position 4:  0 AND 0  retourne 0

Résultat:  0 0 1 0  =  2
Ce qui nous confirme qu'on est justifié de considérer qu'un des deux arguments du AND peut être perçu comme un "masque" pour le second argument.

 

Cette façon de voir les choses peut être plus instructive que celle où on ne considère qu'un AND appliqué bit à bit. Supposons, par exemple, que nous sommes une agence de recrutement et que nos clients sont intéressés à connaître le sexe de nos candidats, s'ils sont déjà employés, s'ils savent conduire et s'ils cherchent un emploi à temps plein. Nous pouvons donc définir les "propriétés" suivantes pour nos candidats:

    Const IsFemale = 1
    Const IsEmployed = 2
    Const CanDrive = 4
    Const FullTime = 8
Si on désire décrire un candidat mâle, ayant actuellement un emploi, sans permis de conduire mais cherchant un emploi à temps plein, on utilisera
IsEmployed + FullTime  ( = 2+8 = 10) 
(pour éviter des erreurs, on utilisera plutôt OR que +. En effet, IsEmployed+IsEmployed+FullTime retourne 12, soit FullTime+CanDrive. Par contre IsEmployed OR IsEmployed OR FullTime retourne 10, en dépits de l'inclusion répétée de IsEmployed)

 Donc, pour notre masque, si le cumul des propriétés de nos candidats est dans la variable AppProps, alors pour chercher si AppProps contient FullTime, on demande

 ? (AppProps AND FullTime) = FullTime

 et de même, on peut vérifier s'il s'agit d'une femme avec:

? (AppProps AND IsFemale) = IsFemale
ou on peut faire les deux recherches en une seule "ligne" comme suit:
? ( AppProps AND (IsEmployed OR IsFemale)) = (IsEmployed OR IsFemale)

ce qui peut être un peu contre intuitif, car on désire et quelqu'un déjà employé et un femme, et, pour se faire, on utilise OR. En fait, si on applique (AppProps AND (IsEmployed OR IsFemale)) à un homme ayant un emploi, le résultat est IsEmployed. Mais puisque IsEmployed <> (IsEmployed OR IsFemale), un tel candidat ne sera pas conservé. Seuls les candidats ayant IsEmployed et IsFemale seront donc bel et bien conservés par cette expression.

Voici un bout de code qui permet d'illustrer ces diverses techniques.

'*************  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  ********************

© 1998-2001, Dev Ashish, All rights reserved. Optimized for Microsoft Internet Explorer