按位左移行为

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

当我调用下面的函数时,它输出为System.out.println("b="+b); //Output: 0 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 ie 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? */ } } 

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

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

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

 01000000 

shift运算符将值提升为int:

 00000000000000000000000001000000 

然后左移2位:

 00000000000000000000000100000000 

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

 00000000 

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

在java中,int是签名的。 为了表示,使用2的补码 。 在此表示中,任何将其高位设置为1的数字都是负数(根据定义)。

因此,当你左移第31位(即int之前的那个)的1时,它变为负数。

 i = a << 2; 

在记忆中:

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

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

在记忆中:

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

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

0011 = 3

0011 << 1 = 0110

0110 = 6

您应该阅读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