按位左移行为

时间:2013-11-07 15:01:02

标签: java bitwise-operators

今天我正在学习左移位操作符(<<)。据我所知,左移位操作符按指定向左移动位。而且我知道转移乘以2。但我很困惑,就像“移位”的含义到底是什么?为什么当用不同类型赋值时输出会有所不同?

当我调用下面的函数时,它会将输出显示为System.out.println("b="+b); //Output: 0

我的问题是:b如何变为0,为什么b被类型化?

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
}

更新(新疑点):

含义是什么“如果将1位移到高位(位31或63),则该值将变为负值”。例如

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?
         */
    }
}

5 个答案:

答案 0 :(得分:5)

当整数在Java中转换为字节时,只保留最低位:

  

将有符号整数缩小转换为整数类型T.   简单地丢弃除n个最低位之外的所有位,其中n是数字   用于表示类型T的位数。除了可能的丢失   有关数值大小的信息,这可能会导致   结果值的符号与输入符号不同   值。

在这种情况下,字节64具有以下二进制表示:

01000000

shift运算符将值提升为int:

00000000000000000000000001000000

然后左移2位:

00000000000000000000000100000000

然后我们将它转​​换回一个字节,所以我们丢弃除了最后8位以外的所有字符:

00000000

因此最终字节值为0。但是,您的整数会保留所有位,因此其最终值确实为256

答案 1 :(得分:2)

在java中,整数已签名。为了表示这一点,使用了2's complement。在此表示中,任何将其高位设置为1的数字都是负数(根据定义)。

因此,当你向左移第31位(即最后一位为int)时,它会变为负数。

答案 2 :(得分:1)

i = a << 2;

在记忆中:

  • 将a(8位)加载到regitry R1(32位)
  • 将注册表R1移至左侧两个位置
  • 将注册表R1(32位)分配给变量i(32位)。

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

在记忆中:

  • 将a(8位)加载到regitry R1(32位)
  • 将注册表R1移至左侧两个位置
  • 将注册表R1(32位)分配给变量b(8位)。 &lt; - 这就是为什么cast(byte)是必要的以及为什么它们只得到移位操作的最后8位

答案 3 :(得分:0)

移位的确切含义正是听起来的样子。 :-)你把它们移到左边。

  

0011 = 3

     

0011&lt;&lt; 1 = 0110

     

0110 = 6

答案 4 :(得分:0)

您应该阅读Java中不同的数据类型及其范围。

让我以简单的方式解释。

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

'byte'是带符号2的补码整数。它可以存储-128到127(包括两者)的值。当你这样做时,

i = a << 2;

你将'a'移位2位,该值应为64 * 2 * 2 = 256.'i'的类型为'int',Java中的'int'可以表示该值。

当你再次离开和转换时,

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

保持低8位,因此该值为0.

您可以在Java中针对不同的原始类型阅读此内容。 http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html