My BitArray Class






2.43/5 (16 votes)
Jun 13, 2006
3 min read

77055

530
A BitArray class with more function
Introduction
There's a BitArray class in namespace System.Collections.BitArray. But there's a big problem in it.
if you define two bytes as:
byte[] bits = new byte[2];
bits[0] = 1;
bits[1] = 3;
And use them in constructor of BitArray class, the bits must be "0000000100000011" because the byte[0] is "00000001"(binary view of 1) and the byte[1] is "00000011"(binary view of 3). Constructor first must use the first byte and then use the second byte.
But it won't !
The bits in the BitArray class will be "100000001100000". as you can see, the constructor first inverse each byte and then use it. and if you inverse all bits you gain "0000001100000001" wich that's not what we want.
Why ?
As i understood the problem come from CPU ! i wrote a thread in MSDN forum http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=466424&SiteID=1. i understood most of our cpu works little-endian (thank's nobugz in MSDN forum) it means they inverse bits.
for example if you send "00000001" to cpu it will store it in ram as "10000000" and when you read it cpu inverse it again and show you "00000001".
so our problem occur when we send "00000001" to cpu, cpu store it in ram as "10000000" and when we want the first bit the cpu return "1".
i think this problem occur in the constructor of System.Collections.BitArray. BitArray class must define a pointer to the first bit of array and start reading bits from there.
The program below show the problem. first it store 1 and 3 in two bytes. then use byte array for constructor. and show you a messagebox contain bits. it's not bad to change byte to int and 16 to 64 to see how problem will change. the constructor will inverse every 32 bits of data (int length)
byte[] bits = new byte[2];
bits[0] = 1;
bits[1] = 3;
BitArray BA = new BitArray(bits);
string st = string.Empty;
for(int i=0; i< 16; i++)
st += Convert.ToInt16(BA.Get(i)).ToString();
MessageBox.Show(st); //source don't contain this test program
My BitArray Class
So i started to write my own bit array class. not even solve this problem also add more functions to it.
Inheritance Problem
First i want to write class that inherits from System.Collections.BitArray. but i don't know why microsoft defined BitArray class as a Sealed( notInheritable) class.
So i declared a ArrayList and store my bits in it. i have tried to my class be similar to BitArray class.
How it work's
I show an example of how my constructor work's for a byte array as an argument:
for each byte in array use Convert.ToString(TheByte,2). this function convert the byte to binary string. if our first byte be 43 this function return "101011". as you can see it's only 6 bit length. for store in our array a byte must be 8 bits length. so we call FixLength function to solve length problem. FixLength add two zero at the begining. and return "00101011"
Now we can add "00101011" to our array. we do this by calling AddBits function. this function add "false" to arrayList for each 0 and add "true" to arrayList for each 1
public JIBitArray(byte[] bits)
{
string st;
foreach(byte b in bits)
{
st = FixLength(Convert.ToString(b,2),8);
AddBits(st);
}
}
private string FixLength(string num,int length)
{
while(num.Length < length)
num = num.Insert(0,"0");
return num;
}
private void AddBits(string bits)
{
foreach(char ch in bits)
{
if(ch == '0')
_Bits.Add(false);
else if(ch == '1')
_Bits.Add(true);
else
throw(new ArgumentException("bits Contain none 0 1 character"));
}
}
we do the same for other constructors.
Functions
i have defined Get, Set, SetAll, Count, Or, Xor, And, Not functions to do the same as Microsoft BitArray class do
And add more functions:
1. ShiftLeft, ShiftRight for shifting bits to left or right
To shift left simply remove bits from left and then add 0 bits to the end
2. GetLong, GetInt, GetByte, GetShort
This functions use to convert our bits to Long Array, Int Array Byte Array and Short Array
I explain one of them:
GetByte
we need to calculate return array length. To do this:
int ArrayBound = (int)Math.Ceiling((double)this._Bits.Count/8);
Then declare array for returning:
byte[] Bits = new byte[ArrayBound];
if out array lenght be 9 bits. we need to return byte array with length of 2. so the array bound will be 2 and it means the lenght of array must be 16 bits. for fixing the length of our array we declare Temp JIBitArray and Fix it length to ArrayBound * ByteLength(which is 8)
JIBitArray Temp = new JIBitArray();
Temp._Bits = this._Bits;
Temp = FixLength(Temp,ArrayBound * 8);
Convert each 8 bits block to a byte by using "Convert.ToByte(string,base)" function.
for
(int i=0; i< Temp._Bits.Count; i += 8){
Bits[i/8] = Convert.ToByte(Temp.SubJIBitArray(i,8).ToString(),2);
}
And then return bits.
3. RemoveBeginingZeros
if you have JIBitArray contain "00001110101" RemoveBeginingZeros return "110101"
4. operators
i have declared operator functions for this class
& And, | Or, ^ Xor, >> ShiftRight, << ShiftLeft
5. SubJIBitArray
it works like SubString function for string class. SubJIBitArray(2,3) for "0110110101" return "101"