Add useful extensions to the BitArray class in C#

The example Use the BitArray class in C# explains how to use the BitArray class. This example adds some useful features to the BitArray class as extension methods.

The following code shows the NumTrue and NumFalse extension methods, which return the number of true and false items in a BitArray respectively.

// Return the number of true values in the BitArray.
static public int NumTrue(this BitArray bits)
{
    int count = 0;
    foreach (bool value in bits) if (value) count++;
    return count;
}
static public int NumFalse(this BitArray bits)
{
    return bits.Count - bits.NumTrue();
}

The NumTrue method simply counts the number of true entries in the BitArray. The NumFalse method subtracts NumTrue from the total number of entries in the BitArray.

The following code shows AndAll and OrAll methods, which return true if the And or Or of all of the values in the BitArray.

// Return the logical And of all of the entries in the array.
static public bool AndAll(this BitArray bits)
{
    foreach (bool value in bits) if (!value) return false;
    return true;
}

// Return the logical Or of all of the entries in the array.
static public bool OrAll(this BitArray bits)
{
    foreach (bool value in bits) if (value) return true;
    return false;
}

The AndAll method loops through the values and returns false if any is false. If all are true, it returns true.

The OrAll method loops through the values and returns true if any is true. If all are false, it returns false.

You could implement the AndAll and OrAll methods by using the NumTrue and NumFalse methods but that would require examining every item in the BitArray. (I'll leave that as a fairly easy exercise.) The methods shown here can sometimes stop searching the values early to save time.

The BitArray class inherits the object class's version of ToString so by default that method displays the class's name "System.Collections.BitArray." The following code shows a few overloaded versions of the ToString method that are display the BitArray's values formatted as text.

// Return a string showing the BitArray's values.
static public string ToString(this BitArray bits, string true_value,
    string false_value, string separator, int group_size,
    string group_separator)
{
    string result = "";
    for (int i = 0; i < bits.Length; i++)
    {
        // Add the value and separator.
        if (bits[i]) result += separator + true_value;
        else result += separator + false_value;

        // Add the group separator if appropriate.
        if ((i + 1) % group_size == 0) result += group_separator;
    }

    // Remove the initial separator.
    if (result.Length > 0) result = result.Substring(separator.Length);
    return result;
}
static public string ToString(this BitArray bits, string true_value,
    string false_value, string separator)
{
    return ToString(bits, true_value, false_value, separator, int.MaxValue, "");
}
static public string ToString(this BitArray bits, string true_value,
    string false_value)
{
    return ToString(bits, true_value, false_value, "");
}

The first overloaded version does the interesting work. It loops through the BitArray's values. Depending on each value, it adds true_value or false_value to the result string followed by a separator. (Note that you can make the separator "" if you don't want to separate the values.) Then if the value's index plus 1 is a multiple of the group_size parameter, the code inserts a group separator. This lets you create values such as 00111100 11000100 10000100 01000000.

The two other overloaded versions let you omit the group separator, and the group and value separators.

The following code shows how the main program demonstrates the BitArray extension methods.

// Demonstrate BitArray extensions.
private void Form1_Load(object sender, EventArgs e)
{
    // Make a BitArray holding IsSquare Xor IsFibonacci.
    BitArray bits = new BitArray(32);
    for (int i = 0; i < bits.Length; i++)
        bits[i] = (IsSquare(i) ^ IsFibonacci(i));

    // Display the result in various ways.
    string txt = "";
    txt += "# True: " + bits.NumTrue() + ", " +
        "# False: " + bits.NumFalse() + ", " +
        "AndAll: " + bits.AndAll() + ", " +
        "OrAll: " + bits.OrAll() +
        Environment.NewLine;
    txt += bits.ToString("T", " ") + Environment.NewLine;
    txt += bits.ToString("X", ".") + Environment.NewLine;
    txt += bits.ToString("1", "0", "", 8, " ") + Environment.NewLine;
    txt += bits.ToString("TRUE", "false", " ");
    txtBits.Text = txt;
    txtBits.Select(0, 0);
}

This code creates a BitArray where the i-th entry is true if [i is a perfect square] XOR [is is a Fibonacci number]. It then demonstrates the NumTrue, NumFalse, AndAll, OrAll, and ToString extension methods.

Others have suggested many additional extension methods for working with BitArrays such as the ability to copy some of a BitArray's values or to convert parts into other data types. For example, you might want to convert a 32 value BitArray into 4 bytes. Those are more specialized and somewhat different in intent than the BitArray (which is really intended to store boolean values not bits) so I'll leave those as exercises. (Let me know if you need any of them and have trouble implementing them.)

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments
  • No comments exist for this post.
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.