<< (左移),>>(右移),>>>(无符号右移)都是java里面的移位运算符。
下面先以一个正数为例子
public static void main(String args[]){
System.out.println("----------以正数10为例子-----------");
byte bt=10;
for(int i=0;i<9;i++){
byte newBt=(byte)(bt<
输出
----------以正数10为例子-----------
10向左移动i=0位后为10
10向左移动i=1位后为20
10向左移动i=2位后为40
10向左移动i=3位后为80
10向左移动i=4位后为-96
10向左移动i=5位后为64
10向左移动i=6位后为-128
10向左移动i=7位后为0
10向左移动i=8位后为0
----------bt-----------
分析一哈,
首先10转换成进制为 0000 1010 这里以基本类型为byte为例,byte类型在java中占一个字节,8位,其它类型如short,int,long等类似,位数比较长,就不逐一举例了
二进制 十进制
原始数字 0000 1010 10
向左移动一位 0001 0100(末尾补零高位丢弃) 20
向左移动两位 0010 1000 (末尾补两个零高位丢弃) 40
向左移动三位 0101 0000 (末尾补三个零高位丢弃) 80
向左移动四位 1010 0000 (末尾补四个零高位丢弃) -96
这个地方注意了,有些人可能会觉得正数移着移着怎么就成负数了,看上面移动四位以后原始数字变为了1010 0000 ,这个时候发现第一位是1,所以我们知道此数是一个负数,二进制最高位代表符号为,0 代表正数,1代表负数 负数的二进制转十进制的方法,先减一,再取反,可以得出二进制代表的正十进制数
1010 0000
减一 1001 1111
取反 0110 0000 转十进制 96
因为之前已经确定它是负数, 所以最终得到-96
向左移动五位 0100 0000 (末尾补五个零高位丢弃) 64
向左移动六位 1000 0000 (末尾补六个零高位丢弃) -128
向左移动七位 0000 0000 (末尾补七个零高位丢弃) 0
向左移动八为 0000 0000 (末尾补七个零高位丢弃) 0
…
接着再以一个负数为例子
public static void main(String args[]){
System.out.println("----------以负数-10为例子-----------");
byte bt=-10;
for(int i=0;i<10;i++){
byte newBt=(byte)(bt<
输出
----------以负数-10为例子-----------
-10向左移动i=0位后为-10
-10向左移动i=1位后为-20
-10向左移动i=2位后为-40
-10向左移动i=3位后为-80
-10向左移动i=4位后为96
-10向左移动i=5位后为-64
-10向左移动i=6位后为-128
-10向左移动i=7位后为0
-10向左移动i=8位后为0
-10向左移动i=9位后为0
----------bt-----------
二进制 十进制
原始数据 1111 0110 -10
向左移动1位 1110 1100 -20
向左移动2位 1101 1000 -40
向左移动3位 1011 0000 -80
向左移动4位 0110 0000 96
向左移动5位 1100 0000 -64
向左移动6位 1000 0000 -128
向左移动7位 0000 0000 0
向左移动8位 0000 0000 0
…
总结,之前有有人说用<<移动几位就是乘以2的几次方,从上面的结果可以看出,这个说法有一定的道理,但不严谨,例如当-10移动四位的时候已经不满足了,
总的来说,<<就是让二进制数向左移动,低位补0,高位超出位数限制的舍弃。
同样先来一个正数为例子,
public static void main(String args[]){
System.out.println("----------以正数10为例子-----------");
byte bt=10;
for(int i=0;i<6;i++){
byte newBt=(byte)(bt>>i);
System.out.println(bt+"向右移动i="+i+"位后为"+newBt);
}
System.out.println("----------bt-----------");
}
输出
----------以正数10为例子-----------
10向右移动i=0位后为10
10向右移动i=1位后为5
10向右移动i=2位后为2
10向右移动i=3位后为1
10向右移动i=4位后为0
10向右移动i=5位后为0
----------bt-----------
二进制 十进制
原始数据 0000 1010 10
向右移动1位 0000 0101(高位补1个0,末位丢弃) 5
向右移动2位 0000 0010 (高位补2个0,末位丢弃) 2
向右移动3位 0000 0001 (高位补3个0,末位丢弃) 1
向右移动4位 0000 0000(高位补4个0,末位丢弃) 0
…
再接着以一个负数为例子
public static void main(String args[]){
System.out.println("----------以负数-10为例子-----------");
byte bt=-10;
for(int i=0;i<6;i++){
byte newBt=(byte)(bt>>i);
System.out.println(bt+"向右移动i="+i+"位后为"+newBt);
}
System.out.println("----------bt-----------");
}
输出
----------以负数-10为例子-----------
-10向右移动i=0位后为-10
-10向右移动i=1位后为-5
-10向右移动i=2位后为-3
-10向右移动i=3位后为-2
-10向右移动i=4位后为-1
-10向右移动i=5位后为-1
----------bt-----------
二进制 十进制
原始数据 1111 0110 -10
向右移动1位 1111 1011(高位补1个1,低位丢弃) -5
向右移动2位 1111 1101 (高位补2个1,低位丢弃) -3
向右移动3位 1111 1110 (高位补3个1,低位丢弃) -2
向右移动4位 1111 1111 (高位补4个1,低位丢弃) -1
向右移动5位 1111 1111(高位补5个1,低位丢弃) -1
总结,正数使用>>右移,高位补0,低位丢弃,
负数使用>>右移,高位补1,低位丢弃
>>>无符号右移
同样先以一个正数为例
public static void main(String args[]){
System.out.println("----------以正数10为例子-----------");
byte bt=10;
for(int i=0;i<6;i++){
byte newBt=(byte)(bt>>>i);
System.out.println(bt+"向右移动i="+i+"位后为"+newBt);
}
System.out.println("----------bt-----------");
}
输出
----------以正数10为例子-----------
10向右移动i=0位后为10
10向右移动i=1位后为5
10向右移动i=2位后为2
10向右移动i=3位后为1
10向右移动i=4位后为0
10向右移动i=5位后为0
----------bt-----------
可以看出,和>>符号的正数右移效果一样
接下来再以一个负数为例
public static void main(String args[]){
System.out.println("----------以负数-10为例子-----------");
byte bt=-10;
for(int i=0;i<6;i++){
byte newBt=(byte)(bt>>>i);
System.out.println(bt+“向右移动i=”+i+“位后为”+newBt);
}
System.out.println("----------bt-----------");
}
输出
----------以负数-10为例子-----------
-10向右移动i=0位后为-10
-10向右移动i=1位后为-5
-10向右移动i=2位后为-3
-10向右移动i=3位后为-2
-10向右移动i=4位后为-1
-10向右移动i=5位后为-1
----------bt-----------
可以看出和>>符号的负数右移效果一样
总结:
由此可看出 >>与 >>>效果相同
正数右移,高位补0,低位丢弃
负数右移,高位补1,低位丢弃
有人说,>>>符号运算正数时和>>相同,但负数不一样,负数运算右移时高位也是补0,
上面是亲测结果,有不同见解的欢迎来电。
总结一个规律,
负数,正数向左移动很多位以后,回归于0
正数向右移动很多位以后,回归于0
负数向左移动很多位以后,回归于-1
本来对这几个运算符之前的印象也比较模糊,学习一哈做个记录,写着写着就清晰了许多,写的有些啰嗦,不喜勿喷
此处为新增补说明
当数据类型为byte,short 时,>>和>>>效果一样, 当数据类型为int 或long型时效果不同
当数据类型为int 或long时,分情况
操作数为正数,>> 与>>>效果相同,高位补0,低位丢弃
操作数为负数时, >>运算时 高位补1,低位丢弃
>>>运算时高位补0,低位丢弃
例子:这里只看>> 和>>>操作负数的情况
------------------------------------------------->>------------------------------------------------------------
public static void main(String args[]){
System.out.println("----------以负数-10使用>>为例子-----------");
int bt=-10;
for(int i=0;i<10;i++){
int newBt=bt>>i;
System.out.println(bt+"向右移动i="+i+"位后为"+newBt);
}
System.out.println("----------bt-----------");
}
输出
----------以负数-10使用>>为例子-----------
-10向右移动i=0位后为-10
-10向右移动i=1位后为-5
-10向右移动i=2位后为-3
-10向右移动i=3位后为-2
-10向右移动i=4位后为-1
-10向右移动i=5位后为-1
-10向右移动i=6位后为-1
-10向右移动i=7位后为-1
-10向右移动i=8位后为-1
-10向右移动i=9位后为-1
----------bt-----------
------------------------------------------------->>>-----------------------------------------------------------------
public static void main(String args[]){
System.out.println("----------以负数-10使用>>>为例子-----------");
int bt=-10;
for(int i=0;i<10;i++){
int newBt=bt>>>i;
System.out.println(bt+"向右移动i="+i+"位后为"+newBt);
}
System.out.println("----------bt-----------");
}
输出
----------以负数-10使用>>>为例子-----------
-10向右移动i=0位后为-10
-10向右移动i=1位后为2147483643
-10向右移动i=2位后为1073741821
-10向右移动i=3位后为536870910
-10向右移动i=4位后为268435455
-10向右移动i=5位后为134217727
-10向右移动i=6位后为67108863
-10向右移动i=7位后为33554431
-10向右移动i=8位后为16777215
-10向右移动i=9位后为8388607
----------bt-----------
二进制 十进制
原始数据 11111111 1111111 11111111 11110110 -10
右移一位 01111111 1111111 11111111 11111011(高位补0,低位丢弃) 2147483643
…
大总结一把
运算符<< 向左移动,不区分正负数,高位丢弃,低位补0
运算符>> 向右移动,区分正负数,分两种情况
正数:高位补0,低位丢弃
负数,高位补1,低位丢弃
运算符>>> 分两种情况
操作数类型是byte,short时,效果和>>一样
操作数类型是int,long时,不分正负数,向右移动,高位补0,低位丢弃