Over a million developers have joined DZone.

BitArray in .NET


It’s been quite a while since the last time I published a post related to .NET programming. Since my focus was on more fundamental aspects of programming languages and compilers, reformatting my mind to address the delicate details of languages and programming has been a challenge. Hopefully, I’m going to write more about .NET in the near future.

There are a set of classes and APIs in the .NET Framework that are less used by ordinary software developers engaged in commercial programming. This is in part due to the fact that such classes are designed with specific intentions by the framework designers, and that they are provided as a way of writing more efficient code. That said, commercial developers could care less about this thank to the good performance of .NET Framework JIT compiler and advancements in hardware.

However, there are many cases where you really need to care about efficiency and write a clean code to accomplish something. A place where this may be happening is in hardware-related programs where you want to avoid any extra overhead on low-level manipulations of hardware interfaces.

Dealing with bits and small integers is one scenario where you may need to have to care more about efficiency. Although you’re probably dealing with small numbers, you’re actually dealing with the bits for each number that matter in size. The .NET Framework has provided some tools to facilitate programming for bits and working with them. One of these classes, that is actually a collection class, is System.Collections.BitArray.

BitArray Class DiagramBitArray class is a compact array of bit values that are represented as Boolean values (true corresponding to 1 and false corresponding to zero). This collection type can be used to store a collection of numbers as their bit values and apply bitwise operators to them in a fast, easy, and efficient manner. One good example of a scenario where such a class can be handy is in implementing programs like the one-level CPU cache simulator that I had implemented in ANSI C because such programs have an intense use of bitwise operators on the bits representing integer numbers. If you read my code and try to imagine writing such a program with C# and its regular types, you can understand how important it is to have specific classes developed for such purposes.

It may be worth noting that BitArray is a serializble and COM visible class that implements ICollection, IEnumerable, and ICloneable interfaces, and is marked as a sealed class preventing you from building subclasses of it. This class provides a handy set of properties and methods to deal with bits as well as good constructors to initiate the class structure.

There are two key points to keep in mind: first, BitArray is working with Int32 type with 32 bits representations so you can’t plug in any larger integer type to this collection unless you write your own code to split larger integers into 32 bits sections, and second, the representation of bits in this class is in reversed order of how they appear naturally meaning that you see the bits from right to left stored from the lower index to the higher index.

You can initiate a BitArray object using one of the following constructors:

  • BitArray(BitArray): Initiates the object by settings all its bits to the corresponding bits in the incoming object.
  • BitArray(Boolean[]): Initiates the object by settings all its bits to the corresponding bits in the incoming array of Booleans.
  • BitArray(Byte[]): Initiates the object by settings all its bits to the corresponding binary representation of the incoming array of Bytes.
  • BitArray(Int32): Initiates the object by creating a specified number of bit slots all set to false.
  • BitArray(Int32[]): Initiates the object by settings all its bits to the corresponding binary representation of the incoming array of integers.
  • BitArray(Int32, Boolean): Initiates the object by creating a specified number of bit slots all set to the default Boolean value passed to it.

This class is offering some properties, too, that are regular properties that you deal with in the .NET Framework among which Count and Length may be more useful in practice that both return the same value which is the number of bits stored.

The main advantage of BitArray is in the methods that it offers for bitwise operations on the bits that it contains. Other than a set of methods inherited from Object base class, it offers the following useful methods:

  • And: Applies the bitwise AND operator between the bits of the current object and an incoming BitArray.
  • Get: Gets an integer index and returns the bit value at that index.
  • Not: Applies the bitwise NOT operator on the bits of the current object.
  • Or: Applies the bitwise OR operator between the bits of the current object and an incoming BitArray.
  • Set: Sets a bit at a specific index that is passed to it as argument.
  • SetAll: Sets all bits in the object to the Boolean argument passed to it.
  • Xor: Applies the bitwise XOR operator between the bits of the current object and an incoming BitArray.

Having discussed the structure of BitArray class, the following simple example can show how to use this class in action.

static void Main(string[] args)
03. Console.Title = "BitArray in .NET";
05. // 6 represented as 00000000 00000000 00000000 00000110
06. int[] six = new int[1] { 6 };
07. BitArray bitArray1 = new BitArray(six);
08. Console.WriteLine("6 is stored as:");
09. PrintBits(bitArray1);
11. // 5 represented as 00000000 00000000 00000000 00000101
12. int[] five = new int[1] { 5 };
13. BitArray bitArray2 = new BitArray(five);
14. Console.WriteLine("5 is stored as:");
15. PrintBits(bitArray2);
17. // 6 AND 5 is equal to 4 that will be stored in bitArray1
18. Console.WriteLine("6 AND 5 is:");
19. PrintBits(bitArray1.And(bitArray2));
21. // 11 represented as 00000000 00000000 00000000 00001011
22. // 14 represented as 00000000 00000000 00000000 00001110
23. int[] elevenfourteen = new int[2] { 11, 14 };
24. BitArray bitArray3 = new BitArray(elevenfourteen);
25. Console.WriteLine("11 and 14 are stored as:");
26. PrintBits(bitArray3);
28. // Initiate 64 bits all set to true
29. BitArray bitArray4 = new BitArray(64, true);
30. Console.WriteLine("Not of 64 bits of true is:");
31. PrintBits(bitArray4.Not());
33. Console.WriteLine("Convert the array of bits for 4 to its integer");
34. Console.WriteLine(BitArrayToInt(bitArray1));
36. Console.ReadLine();

Here I use one of the simplest constructors of BitArray to set its bits to the binary representation of a single integer, 6, and then print out the bits. Then I create another BitArray for number 5 and print its bits and use this number to apply a bitwise AND operator on my two BitArray objects and print the result. Note that the operations on BitArray are mutable so the result of the operation will be stored in the caller object and here bitArray1 object will have the bits set to number 4.

The next piece of code is using another constructor to set the bits to binary representation of two integer numbers, 11 and 14, and print the result followed by using yet another type of constructor to initialize a BitArray object with 64 bit slots all set to true. The bitwise NOT operator is called on this object and results are printed out.

The last step is featuring a common scenario that may happen with BitArray which is the conversion of the array of bits to its original integer representation that is done with a helper method called BitArrayToInt which I will explain later.

I’ve used two helper functions in this implementation. The first one is PrintBits that simply prints out the bit values for an incoming BitArray object assuming that it contains integer numbers of 32 bits length. If there are more than one integers stored in the array, it will print them all automatically.

private static void PrintBits(IEnumerable bits)
03. int i = 0;
04. foreach (bool bit in bits)
05. {
06. if ((i % 8 == 0) && (i != 0))
07. Console.Write(" ");
09. Console.Write("{0,2}", ((bit == true) ? "T" : "F"));
11. i++;
13. if (i > 31)
14. {
15. i = 0;
16. Console.WriteLine();
17. }
18. }
19. Console.WriteLine();
The second helper function is BitArrayToInt that gets a BitArray object as its argument and returns the integer representation assuming that the BitArray is storing a single integer even though it is possible to modify this function to work for multiple integers as well.
private static int BitArrayToInt(BitArray bitArray)
3. int[] array = new int[1];
4. bitArray.CopyTo(array, 0);
5. return array[0];

Someone without a good understanding of computer principles would implement this function by a set of verbose loops trying to find the exact value of each bit at each position and summing the results, but this function can work with a very simple technique relied on the nature of number representation in computers.


If you’re interested in downloading the code, I have published the source code sample for this post.


Published at DZone with permission of Keyvan Nayyeri. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}