按位左移行为
今天我正在学习左移位操作符( <<
)。 据我所知,左移位操作符按指定向左移动位。 而且我知道转移乘以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