-->

Bitwise left shift behaviour

2020-07-13 09:50发布

问题:

Today I was learning about the left shift bit operator (<<). As I understand it the left shift bit operator moves bits to the left as specified. And also I know multiply by 2 for shifting. But I am confused, like what exactly is the meaning of "shifting bits" and why does the output differ when value is assigned with a different type?

When I call the function below, it gives output as System.out.println("b="+b); //Output: 0

And my question is: how does b become 0 and why is b typecasted?

public void leftshiftDemo()
{
    byte a=64,b;
    int i;
    i=a << 2;
    b=(byte)(a<<2);
    System.out.println("i="+i); //Output: 256    i.e 64*2^2
    System.out.println("b="+b); //Output: 0   how & why b is typecasted
}

Update (new doubt):

what does it mean "If you shift a 1 bit into high-order position (Bit 31 or 63), the value will become negative". eg.

public void leftshifHighOrder()
{
    int i;
    int num=0xFFFFFFE;

    for(i=0;i<4;i++)
    {
        num=num<<1;
        System.out.println(num);
        /*
         * Output:
         * 536870908
         * 1073741816
         * 2147483632
         * -32   //how this is -ve?
         */
    }
}

回答1:

When integers are casted to bytes in Java, only the lowest order bits are kept:

A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.

In this case the byte 64 has the following binary representation:

01000000

The shift operator promotes the value to int:

00000000000000000000000001000000

then left shifts it by 2 bits:

00000000000000000000000100000000

We then cast it back into a byte, so we discard all but the last 8 bits:

00000000

Thus the final byte value is 0. However, your integer keeps all the bits, so its final value is indeed 256.



回答2:

In java, ints are signed. To represent that, the 2's complement is used. In this representation, any number that has its high-order bit set to 1 is negative (by definition).

Therefore, when you left-shift a 1 that is on the 31st bit (that is the one before last for an int), it becomes negative.



回答3:

i = a << 2;

in memory:

  • load a (8 bits) into regitry R1 (32 bits)
  • shift registry R1 to the left two position
  • assign registry R1 (32 bits) to variable i (32 bits).

b = (byte)(a << 2);

in memory:

  • load a (8 bits) into regitry R1 (32 bits)
  • shift registry R1 to the left two position
  • assign registry R1 (32 bits) to variable b (8 bits). <- this is why cast (byte) is necessary and why they get only the last 8 bits of the shift operation


回答4:

The exact meaning of shifting bits is exactly what it sounds like. :-) You shift them to the left.

0011 = 3

0011 << 1 = 0110

0110 = 6



回答5:

You should read about different data types and their ranges in Java.

Let me explain in easy terms.

byte a=64,b;
int i;
i=a << 2;
b=(byte)(a<<2);

'byte' in Java is signed 2's complement integer. It can store values from -128 to 127 both inclusive. When you do this,

i = a << 2;

you are left shifting 'a' by 2 bits and the value is supposed to be 64*2*2 = 256. 'i' is of type 'int' and 'int' in Java can represent that value.

When you again left shift and typecast,

b=(byte)(a<<2);

you keep your lower 8 bits and hence the value is 0.

You can read this for different primitive types in Java. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html