Hi All,

I am trying to understand shift operator which is used in my project. What I came to know from google is that Bit shifting allows for compact storage of similar data as a single
integral value.

But how does that work. and what is the advantage. Can you explain me the part below program whats exactly happening in below lines. The code is taken from

http://www.codeproject.com/KB/graphics/dicomImageViewer.aspx (Tnx to Amarnath S)

int vr = (b0 << 8) + b1; and case UT: ??

This programe reads a binary file, in medical terms a dicom file, which is basically a binary file.


Getting 4 bytes from a dycom file like this:

byte b0 = GetByte();   // GetByte() is a private method that returns a single byte.
            byte b1 = GetByte();
            byte b2 = GetByte();
            byte b3 = GetByte();

Then doing this:

int vr = (b0 << 8) + b1; // not sure what is happening here

Then a switch statement:

switch(vr)
	{

		// Again didn get whats happening in case UT and QQ
		// where UT = 0x5554, is a constant declared above in the file		
		case UT:  
                    // Explicit VR with 32-bit length if other two bytes are zero
                    if ((b2 == 0) || (b3 == 0)) return GetInt();
                    // Implicit VR with 32-bit length
                    vr = IMPLICIT_VR;
                    if (littleEndian)
                        return ((b3 << 24) + (b2 << 16) + (b1 << 8) + b0);
                    else
                        return ((b0 << 24) + (b1 << 16) + (b2 << 8) + b3);
                    // break; // Not necessary

		case QQ: // where QQ = 0x3F3F, is a constant declared above in the file
                    // Explicit vr with 16-bit length
                    if (littleEndian)
                        return ((b3 << 8) + b2);
                    else
                        return ((b2 << 8) + b3);

	}

Can someone please give me some idea on this. What exactly might be happening in the lines having shift operators.

am little confused with bits and bytes..

hoping to get some reply.
Thanks a lot.

What I came to know from google is that Bit shifting allows for compact storage of similar data as a single integral value.

It's not just shifting, and that's not the only use of the bitwise operators. Since a byte is the smallest addressable unit in C#, that's typically the smallest object one works with. But bytes are comprised of bits, and the bitwise operators allow you to work at an even smaller granularity than bytes when it makes sense to do so.

Compact storage of flags is one such use. A flag is either on or off, so there are really only two values. Rather than have an array or list of N bool objects (which still consume one byte of storage each), you can use an object with a sufficient number of bits, and then use each bit as a flag. For example with eight flags:

using System;

class Program {
    static void Main()
    {
        bool[] flagList = new bool[8] { true, false, true, true, false, true, true, false };
        byte flagByte = 0xB6;

        Console.WriteLine("flagList size: " + flagList.Length * sizeof(bool));
        Console.WriteLine("flagByte size: " + sizeof(byte));

        // List the flags in flagList
        foreach (bool flag in flagList)
            Console.Write(Convert.ToInt32(flag));

        Console.WriteLine();

        // List the flags in flagByte
        for (int bit = 7; bit >= 0; bit--)
            Console.Write((flagByte >> bit) & 0x1);

        Console.WriteLine();
    }
}

Notice how the same information was stored in 1/8th of the space using bitwise operators in the above program. This is a significant savings, and could potentially make all the difference in memory constrained applications.

int vr = (b0 << 8) + b1; // not sure what is happening here

b0 is shifted left by the size of a byte, then b1 is added to that result. This is the bitwise form of concatenation:

b0 = 00111010
b1 = 10101100

00111010
       8 <<
--------
00111010 00000000
         10101100 +
-----------------
00111010 10101100

The shift is used to make room for a concatenated byte, and the code you posted does this for both a two byte integer (16-bits) as well as a four byte integer (32-bits). As long as the destination type has space to hold both the shifted bits and the concatenated bits, all is well.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.