Aide mémoire : Détections de flags…

Aide mémoire (Développement) / Uncategorized

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;
    }