Bonjour,
Dans un programme, je dois manipuler des bits au sein de bytes.
C# semble complètement dénué de fonction complète et optimisée pour gérer ça (BitArray ne permet par exemple même pas de compter le nombre de bits à 1).
J'ai donc cherché un peu à droite à gauche des solutions plus bas niveau, et je tente de les transformer en une classe d'extension pour le type byte histoire de les avoir sous la main facilement.
J'ai donc par exemple trouvé quelques fonctions :
http://graphics.stanford.edu/~seande...tsSetKernighan
Et donc adapté sans trop de problème ça en méthode d'extension :
Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 unsigned int v; // count the number of bits set in v unsigned int c; // c accumulates the total bits set in v for (c = 0; v; c++) { v &= v - 1; // clear the least significant bit set }
Devient donc :
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 public static int PopCountBits(this byte aByte) { int c; // c accumulates the total bits set in aByte for (c = 0; aByte > 0; c++) { aByte &= (byte)(aByte - 1); // clear the least significant bit set } return c; }
Et donc j'arrive sur des fonctions déjà en C# pour lire et mettre à jour un bit donné dans un byte :
https://arkonica.wordpress.com/2012/...t-from-a-byte/
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 public static void Set(ref byte aByte, int pos, bool value) { if (value) { //left-shift 1, then bitwise OR aByte = (byte)(aByte | (1 << pos)); } else { //left-shift 1, then take complement, then bitwise AND aByte = (byte)(aByte & ~(1 << pos)); } } public static bool Get(byte aByte, int pos) { //left-shift 1, then bitwise AND, then check for non-zero return ((aByte & (1 << pos)) != 0); }
Si je les utilise telles qu'elles, pas de souci, ça fonctionne.
En revanche, quand je transforme Set en méthode d'extension, bah marche plus
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 public static void Set(this byte aByte, int pos, bool value) { if (value) { //left-shift 1, then bitwise OR aByte = (byte)(aByte | (1 << pos)); } else { //left-shift 1, then take complement, then bitwise AND aByte = (byte)(aByte & ~(1 << pos)); } }
L'intellisense m'indique une assignation inutile à aByte.
Pourtant ça compile et s'exécute convenablement. En revanche... bah ça fait que dalle !
Une méthode d'extension ne peut pas modifier la valeur de l'instance ?
En effet, ça fait bizarre d'avoir un this dans une méthode statique (liste des opérateurs) mais en pas pouvoir utiliser this ensuite... et visiblement ne pas pouvoir modifier non plus la variable correspondante sans pour autant qu'elle soit readonly !
Quelqu'un peu éclairer ma lanterne ???
-- Edit : trouvé
https://docs.microsoft.com/fr-fr/dot...edefined-types
Il faut rajouter "ref" (this ref nan mais z'ont fumé quoi ? :o)
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 public static void SetBit(this ref byte aByte, int pos, bool value) { if (value) { //left-shift 1, then bitwise OR aByte |= (byte)(1 << pos)); } else { //left-shift 1, then take complement, then bitwise AND aByte &= (byte)~(1 << pos)); } }
Partager