Having a Little “Bit” of Fun with C#

Having a Little “Bit” of Fun with C#

Recently in the forum someone asked about bits in a byte and how it is populated into a bit array

http://social.msdn.microsoft.com/Forums/vstudio/en-US/6c3fe986-d347-44e9-b310-cae9c25f1d9d/about-bytes-and-bits

 
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 
Sort by: Published Date | Most Recent | Most Useful
Comments
  • hos is this fun?.... i really do want to get it.

Page 1 of 1 (1 items)