tags:

views:

626

answers:

4
/*   I can not understand this operatore (c# reference)  */

class MainClass1
{
 static void Main()
    {
        int i = 1;
        long lg = 1;
        Console.WriteLine("0x{0:x}", i << 1);
        Console.WriteLine("0x{0:x}", i << 33);
        Console.WriteLine("0x{0:x}", lg << 33);
    }
}

/*
Output:
0x2
0x2
0x200000000
*/

class MainClass2
{
     static void Main()
     {
         int a = 1000;
         a <<= 4;
         Console.WriteLine(a);
     }
}

/*
Output:
16000
*/
+19  A: 

<< is the left-shift operator; this takes the binary representation of a value, and moves all the bits "n" places to the left (except for "mod", see "1"), back-filling with zeros.

>> is the right-shift operator; this does nearly the opposite (moving to the right), except for signed values (i.e. those that can be negative) it back-fills with 1s for negative values, else zeros.

1:

The shift operator is essentially "mod" the width of the data. An int is 32 bits, so a left shift of 33 (in Int32) is exactly the same as a left shift of 1. You don't get all zeros. A long is 64 bits, so a left-shift of 33 gives a different answer (original times 2^33).

2:

Each left shift (within the data width) is the same (for integers) as x2 - so <<4 is x2x2x2x2 = x16.

This is simple binary:

0000000001 = 1

<< goes to

0000000010 = 2

<< goes to

0000000100 = 4

<< goes to

0000001000 = 8
Marc Gravell
Hi, may i ask you to explain it more ?in the first one why i have 0x200000000 and in the second one why i have 16000?thank you so much
Sara S
That is like saying "why is 1 * 50000 different to 1000 * 8" - because you are doing very different things. The first is 2^33 ("power of"), the second is 1000*16.
Marc Gravell
ok I understand the difference between 2^33 and 1000*16i want to know why 2^32
Sara S
33 is int (2^ 5) now for changing to long (2^ 6) why 2^33? thank you
Sara S
1 << 1 = 2 = is 2^1; 1 << 2 = 4 = 2 ^ 2; 1 << 33 = ... = 2 ^ 33 (for long; not for int)
Marc Gravell
thank you. I am looking for a formula in the second one I have a= 1000 << 4 , 1000 is equal 1111101000in binary , ????????????????I dont know how you find 1000*16,may I ask you to give me a formula to understand it better?
Sara S
as you said in example 1 we have 3 outputoutput 1 is 0x2 because both of them are int. output 2 is 0x2 again because 1 and 33 are both int. output 3 is 0x200000000 because 1 is long and 33 is int as you said it is 2^33.
Sara S
so now for the sencond example we have 4 and 1000 that both of them are int?why 1000*16 ???? what is the difference between second example and second output of the first example? thank you so much
Sara S
Each left shift is x2. So 4 left shifts (<<4) is x2x2x2x2 = x16. So 1000 << 4 = 1000 * 16 = 16000. With the << 33 and int: 33 % 32 = 1, so << 33 is the same as << 1, and << 65 is the same as << 1, as is << 97. Only the remainder div 32 is important with int. With long, it is the remainder div 64.
Marc Gravell
+2  A: 

Just to expand on Marc's answer a little (Marc, feel free to include this in yours and I'll delete this answer) this is specified in section 7.8 of the spec:


The predefined shift operators are listed below.

Shift left:

  • int operator <<(int x, int count);
  • uint operator <<(uint x, int count);
  • long operator <<(long x, int count);
  • ulong operator <<(ulong x, int count);

The << operator shifts x left by a number of bits computed as described below.

The high-order bits outside the range of the result type of x are discarded, the remaining bits are shifted left, and the low-order empty bit positions are set to zero.

Shift right:

  • int operator >>(int x, int count);
  • uint operator >>(uint x, int count);
  • long operator >>(long x, int count);
  • ulong operator >>(ulong x, int count);

The >> operator shifts x right by a number of bits computed as described below.

When x is of type int or long, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero if x is non-negative and set to one if x is negative.

When x is of type uint or ulong, the low-order bits of x are discarded, the remaining bits are shifted right, and the high-order empty bit positions are set to zero.

For the predefined operators, the number of bits to shift is computed as follows:

When the type of x is int or uint, the shift count is given by the low-order five bits of count. In other words, the shift count is computed from count & 0x1F.

When the type of x is long or ulong, the shift count is given by the low-order six bits of count. In other words, the shift count is computed from count & 0x3F.

If the resulting shift count is zero, the shift operators simply return the value of x.


Jon Skeet
I appritiate your help.
Sara S
A: 

A few more notes for the novice programmer:

Why use shit operators? They don't seem to do much. Well, there are 2 reasons:

  1. they are fast. really fast. Because nearly all CPUs have shift registers, meaning the shifting operation is done in the hardware, in the minimum amount of effort (cycles).

  2. because they are fast, a lot of protocols and standards are designed to take advantage of this. For example IP address operations, checking a CRC, graphic operations etc.

Bogdan Gavril
A: 

"The shift operator is essentially "mod" the width of the data."

Rubbish! If the amount of the shift is greater than, or equal to, the width of the data, the result is undefined. Do not expect the same 'mod' operation that you happen to have seen, to happen with different compilers, or different versions of the same compiler, or in different shift situations in the same program, or when anything else changes. That's what 'undefined' means.

greg