希望这次写下来能记住,不要再范迷糊啦。
左移
java仅有一种左移运算符(<<),就是将当前数值左移n位,低位补0。需要说清楚的是,在虚拟机中数值是以补码的形势存储的,那请问左移n位移动的是原码还是补码呢???
其实这个问题我也迷糊了好久,刚刚做了实验就记录下。
正答:左移n位移动的是补码。接下来就举几个例子。
int a=1;
a<<=1;//a=2,没啥疑问
int b=1;
b<<=31;//b=-2^31,左移之后补码为0x80000000,转换成原码(除符号位之外,取反,+1),为0x800000000,-2^32;。
int c=1;
c<<=32;//c=1,按照“左移n位移动的是补码”,那输出的不就应该是0吗;但java编译器会对<<左边的数值按照当前数值类别(int32,long64)取模,就相当于c<<=0。
int d=3;
d<<30;//d=-2^30,左移之后补码为0xC0000000,转换成原码(除符号位之外,取反,+1),为0xC0000000;
右移
讲完了左移,右移就简单多了。右移分两种带符号右移,无符号右移
符号右移
带符号右移(>>),顾名思义就是右移的时候,若是正数,高位补0;若是负数,高位补1。
int f=-2147483648;
f>>=1;//f=-1073741824,左移之前补码f=0x80000000,左移之后补码f=0xC0000000,转换成原码f=C0000000,f=-2^30
算术右移
算术右移,即不带符号右移(>>>),右移的时候,高位补0;
int g=-2147483648;
g>>>=1;//g=1073741824,左移之前补码f=0x80000000,左移之后补码f=0x40000000,正数转换成原码(不改变),原码g=0x40000000,2^30。