Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Recently in the forum someone asked about bits in a byte and how it is populated into a bit array
The thread originator first populated a byte array and fed that into a bit array…
byte [] byteArray = new byte[] { 1 };
BitArray bitArray = new BitArray(byteArray);
When he went to print the array to his surprise the output was backward to what he expected…
//Simplification of what he did is this
for (int i = 0; i < bitArray.Length; i++)
{
Console.Write(Convert.ToInt16(bitArray[i]));
//note: without the convert to an int the output would be true and false
//10000000 would output truefalsefalsefalsefalsefalsefalse
}
He should have done something like this starting with the most significant bit
for (var idx = bitArray.Length - 1; idx >= 0; idx--) //Parse from left most bit to right most bit
{
Console.Write("{0}", Convert.ToInt16(bitArray[idx]));
}
Console.WriteLine();
//note: without the convert to an int the output would be true and false
//00000001 would output falsefalsefalsefalsefalsefalsefalsetrue
Let’s explore why… here is a byte represented by a string of bits (00000001)
When a byte is converted to a bit array it starts with position 0 and goes up to 7. The bit positions represent values and adding all the positions set to 1 or true totals the value of the converted byte. A byte starts with the lowest significant bit on the right and the most significant bit on the left
So what does all this mean?
The logic of a byte is each position represents a value the lowest or least significant bit represents 1, the next bit or next one to the left of it is 2, the next 4 and so on…
Bit position 7 6 5 4 3 2 1 0
Value of position 128 64 32 16 8 4 2 1
Let’s see what some strings of eight bits or a byte equals
Here we have just the first or lowest significant bit set to true or 1 which also represent the value 1, all others unset
00000001 = 1 // 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1
Here we have the least significant bit set, the next one unset and the next following one set… all others unset
00000101 = 5 // 0 + 0 + 0 + 0 + 0 + 0 + 4 + 1
Here we have another… see what it is…
10001001 = 137 // 128 + 0 + 0 + 0 + 8 + 0 + 0 + 1
Going beyond the context of the forum post we are now going to talk about bitwise operations
AND ( & sign in C#, And in vb.nET )
OR (Inclusive OR) ( | sign in C#, Or in vb.nET )
NOT ( ~ sign in C#, Not in vb.nET)
XOR (Exclusive OR) ( ^ sign in C#, Xor in vb.nET)
Left Shift ( << sign in C# and vb.nET)
Right Shift ( >> sign in C# and vb.nET)
And finally build on shift with an example of Circular ***
The AND ( & sign in C#, And in vb.nET ) will take the corresponding placed bits and compare them and output according the following logic table
A helper method providing AND functionality to a pair of bytes
private static byte ByteAND(byte val1, byte val2)
{
return Convert.ToByte(val1 & val2);
}
//use it as follows
byte andVal1 = 6; //00000110
byte andVal2 = 5; //00000101
byte outputAND = ByteAND(andVal1, andVal2);
//returns 4 or 00000100
The OR (Inclusive OR) ( | sign in C#, Or in VB.NET ) will take the corresponding placed bits and compare them and output according to the following logic table
A helper method providing OR functionality to a pair of bytes
private static byte ByteOR(byte val1, byte val2)
{
return Convert.ToByte(val1 | val2);
}
//use as follows
byte orVal1 = 6; //00000110
byte orVal2 = 5; //00000101
byte outputOR = ByteOR(orVal1, orVal2);
//retuturns 7 or 00000111
The NOT ( ~ sign in C#, Not in VB.NET) ) will take the corresponding placed bits and compare them and output according to the following logic table
A helper method providing NOT functionality to a pair of bytes
private static byte ByteNOT(byte val1)
{
return (byte)~val1;
}
//use as follows
byte notVal1 = 1; //00000001
byte outputNOT = ByteNOT(notVal1);
//returns 254 or 11111110
The XOR (Exclusive OR) ( ^ sign in C#, Xor in VB.NET) will take the corresponding placed bits and compare them and output according to the following logic table
A helper method providing NOT functionality to a pair of bytes
private static byte ByteXOR(byte val1, byte val2)
{
return Convert.ToByte(val1 ^ val2);
}
//use as follows
byte xorVal1 = 6; //00000110
byte xorVal2 = 5; //00000101
byte outputXOR = ByteXOR(xorVal1, xorVal2);
//returns 3 or 00000011
Note: In the following if you click the images you will see the animation
Next are shift operations
Left Shift to shift all bits to the left a specified number of times
private static byte ShiftLeft(byte val1, int shift)
{
return (byte)(val1 << shift);
}
//use as follows
byte leftVal = 1;
byte outputLeftShift = ShiftLeft(leftVal, 1); //Shift one bit to left
//returns 2 or 00000010
**Right Shift to shift all bits to the left a specified number of times
private static byte ShiftRight(byte val1, int shift)
{
return (byte)(val1 >> shift); //or val1 << (8 - shift));
}
//use as follows
byte rightVal = 2;
byte outputRightShift = ShiftRight(rightVal, 1); //Shift one bit to right
//returns 1 or 00000001
**Now we are going to create a circular shift method and note C# doesn’t include a built in operator for this… We are going to create a method that does both right and left **
private static byte CircularShift(byte val, int shift, bool rightLeft)
{
byte newVal = 0;
if (rightLeft)
{
//Shift right
newVal = (byte)(val >> shift | val << (8 - shift));
}
else if (!rightLeft)
{
//Shift left
newVal = (byte)(val << shift | val >> (8 - shift));
}
return newVal;
}
//use as follows
byte circRightVal = 1; //00000001
byte outputCircRight = CircularShift(circRightVal, 1, true);
//returns 128 or 10000000
byte circLeftVal = 128; //10000000
byte outputCircLeft = CircularShift(circLeftVal, 1, false);
//returns 1 or 00000001