Aide mémoire pour détecter la présence d’un flag dans un entier…
1. Introduction
2. Algèbre booléenne et Opérateurs
3. Méthodes utiles
1. Introduction
Il arrive parfois d’utiliser un entier à la place d’un tableau de byte, pour des raisons particulières que j’aborderais pas ici.
Exemple :
Flag | Valeur |
A | 1 |
B | 2 |
C | 4 |
D | 8 |
On notera que les valeurs sont des puissances de 2.
Si ma variable i (de type int) contient les flags, A et C, alors i = A + C <=> 1 + 4 <=> 5.
Pour paramétrer la valeur la première fois, rien de bien compliqué, il suffit d’ajouter les entiers.
Pour ajouter un flag sur un entier existant, c’est un poil plus compliqué :
Si i vaut déjà 5, et qu’on veut etre sur que le flag C soit présent, on ne peut pas simplement additionner la valeur de C à i:
i = 5 -> i = i + C -> i =5 + 4 -> i = 9 <=> i = A + D
Il faut donc vérifier que le flag ne soit pas présent avant… ou utiliser une autre méthode : l’algèbre booléene.
2. Algèbre booléenne et Opérateurs
Mon but ici n’est pas de faire un cours complet, juste un résumé de base sur l’algèbre booléenne :
A | B | NON A | NON B | A ET B | A OU B |
0 | 0 | 1 | 1 | 0 | 0 |
0 | 1 | 1 | 0 | 0 | 1 |
1 | 0 | 0 | 1 | 0 | 1 |
1 | 1 | 0 | 0 | 1 | 1 |
L’opérateur NON peut être écrit de de manière en Java: soit avec ! (dans le cas d’un booléen) soit avec ~. L’opérateur ~ inverse les bits d’un nombre, donc 8 (décimal) qui s’écrit 1000 en binaire (mémoire) et deviendrait 1…10111 (toujours en binaire et en mémoire) en passant par l’opérateur ~.
L’opérateur ET peut être écrit de de manière en Java: soit avec && (toujours pour un booléen) soit avec &. Dans ce cas, pour chaque bit de même poids en mémoire, l’opération A ET B de la table précédente est effectuée:
12 & 4 <=> 1100 & 100 <=> 0100 <=> 4
8 & 8 <=> 1000 & 1000 <=> 1000 <=> 8
L’opérateur OU peut être écrit de de manière en Java: soit avec || (toujours pour un booléen) soit avec |. Dans ce cas, pour chaque bit de même poids en mémoire, l’opération A OU B de la table précédente est effectuée:
12 | 4 <=> 1100 | 100 <=> 1100 <=> 12
8 | 4 <=> 1000 | 100 <=> 1100 <=> 12
3. Méthodes utiles
/** * Check if the given mask is used in value. * @param value - value to check * @param mask - mask to used * @return boolean */ public static boolean isMatch(final int value, final int mask) { return (value & mask) != 0; } /** * Check if the value use only the mask ones. * @param value - value to check * @param mask - mask to used * @return boolean */ public static boolean isMatchOnly(final int value, final int mask) { return ((value & mask) != 0) && (value & ~mask) == 0; } /** * Add or remove mask to value. * @param value - old value * @param mask - mask to add or remove * @param isAddition - true to add, false to remove * @return new value */ public static int setValue(final int value, final int mask, final boolean isAddition) { if (isAddition) { return value | mask; } return value & ~mask; }