二进制中左移、右移、无符号右移规则

前提知识

  • 正数的原码,反码以及补码都是一样的
  • 负数的反码是原码的符号位不变,数值位按位取反
  • 负数的补码是符号位不变,数值位在反码的基础上加1
  • 正数的符号位是用0来表示,负数的符号位使用1来表示

二进制左移(<<)

左移的话就比较简单了,因为他不牵扯到符号的问题,符号位不变就行,左移几位就要给右侧末尾加几个零就可以
左移1位,相当于乘2,右移动一位相当于除以2
首先左移的标识是: <<
这里首先看正数的左移
例1 正数8

二进制:1000
原码:1000   
反码:1000
补码:1000
左移2位: 8 << 2
8的补码左移2位(向左移2位,右侧补2个零)后:100000
8的补码左移2位后的补码:100000
8的补码左移2位后的反码:100000
8的补码左移2位后的原码:100000
最终转换成10进制后:32

相当于: 8 乘以 22次方

例2 正数55

二进制:110111
原码:110111   
反码:110111
补码:110111
左移3位: 8 << 3
55的补码左移3位(向左移3位,右侧补3个零)后:110111000
55的补码左移3位后的补码:110111000
55的补码左移3位后的反码:110111000
55的补码左移3位后的原码:110111000
最终转换成10进制后:440
相当于: 55 乘以 23次方

例3 负数 -8

二进制:1000 1000
原码:1000 1000   
反码:1111 0111
补码:1111 1000
左移3位: -8 << 3
 -8的补码左移3位(向左移3位,右侧补3个零)后:1111 1000 000
 -8的补码左移3位后的补码:1111 1100 000
 -8的补码左移3位后的反码:1111 0111 111
 -8的补码左移3位后的原码:1000 1000 000
最终转换成10进制后:-64
相当于: -8 乘以 23次方

例4 负数 -83

二进制:1101 0011
原码:1101 0011  
反码:1010 1100
补码:1010 1101
左移3位: -83 << 3
-83的补码左移3位(向左移3位,右侧补3个零)后:1010 1101 000
-83的补码左移3位后的补码:1010 1101 000
-83的补码左移3位后的反码:1010 1100 111
-83的补码左移3位后的原码:1101 0011 000
最终转换成10进制后:-664
相当于: -83 乘以 23次方

二进制右移

对于正数而言,有符号右移和无符号右移都是一样,左侧都补的是0,与符号位相同
但是对于负数而言,有符号右移和无符号右移是不一样的

有符号二进制右移(>>)

 对于有符号右移而言,不论是正数还是负数,右移几位,就给左侧加几个符号位

这里例子都采用的32进制,int类型占32位,具体结果要看系统中int占位,**** 代表很多个1或者0,具体要看它前面是1还是0 。
例1 正数8

二进制:0000 **** 1000  
原码:0000 ****  1000   
反码:0000 **** 1000
补码:0000 **** 1000
右移2位: 8 >> 2
8的补码右移2位(向右移2位,左侧补2个零,实际上就是补两个符号位,正数符号位为0,这里就补20)后,0000 **** 0010
8的补码右移2位后的补码:0000 **** 0010  
8的补码右移2位后的反码:0000 **** 0010
8的补码右移2位后的原码:0000 **** 0010
最终转换成10进制后:2

例2 正数55

二进制:0000 **** 0011 0111
原码:0000 **** 0011 0111   
反码:0000 **** 0011 0111
右移3位: 8 >> 3
55的补码右移3位(向右移3位,左侧补3个零,实际上就是补3个符号位,正数符号位为0,这里就补30)后:0000 **** 0110
55的补码右移3位后的补码:0000 **** 0110  
55的补码右移3位后的反码:0000 **** 0110
55的补码右移3位后的原码:0000 **** 0110
最终转换成10进制后:6

例3 负数 -8

二进制:1000 0000 **** 1000
原码:1000 0000 **** 1000   
反码:1111 **** 0111
补码:1111 **** 1000
右移3位: -8 >> 3
8的补码右移3位(向右移3位,左侧补31,实际上就是补3个符号位,负数符号位为1,这里就补31)后:1111 **** 1111
8的补码右移3位后的补码:1111 **** 1111
8的补码右移3位后的反码:1111 **** 1110
8的补码右移3位后的原码:1000 **** 0001
最终转换成10进制后:-1

例4 负数 -83

二进制:1000 **** 0101 0011
原码:1000 **** 0101 0011  
反码:1111 **** 1010 1100
补码:1111 **** 1010 1101
右移3位: -83 >> 3
-83的补码右移3位(向右移3位,左侧补31,实际上就是补3个符号位,负数符号位为1,这里就补31)后:1111 **** 1111 0101
-83的补码右移3位后的补码:1111 **** 1111 0101
-83的补码右移3位后的反码:1111 **** 1111 0100
-83的补码右移3位后的原码:1000 **** 0000 1011
最终转换成10进制后:-11

无符号二进制右移(>>>)

无符号右移>>> :不管正负标志位为0还是1,将该数的二进制码整体右移,左边部分总是以0填充,右边部分舍弃。

这里例子都采用的32进制,int类型占32位,具体结果要看系统中int占位,**** 代表很多个1或者0,具体要看它前面是1还是0 。

例1 正数8

二进制:0000 **** 10000是符号位  000 1000是数值位)
原码:0000 **** 1000   
反码:0000 **** 1000
补码:0000 **** 1000
右移2位: 8 >>> 2
8的补码右移2位(向右移2位,左侧补2个零)后,0000 **** 0010
8的补码右移2位后的补码:0000 **** 00100是符号位  000 0010是数值位)
8的补码右移2位后的反码:0000 **** 0010
8的补码右移2位后的原码:0000 **** 0010
最终转换成10进制后:2

例2 正数55

二进制:0000 **** 0011 0111
原码:0000 **** 0011 0111   
反码:0000 **** 0011 0111
右移3位: 8 >>> 3
55的补码右移3位(向右移3位,左侧补3个零)后:0000 **** 0000 0110
55的补码右移3位后的补码:0000 **** 0000 0110  0是符号位  000 0110是数值位)
55的补码右移3位后的反码:0000 **** 0000 0110
55的补码右移3位后的原码:0000 **** 0000 0110
最终转换成10进制后:6

例3 负数 -5

二进制:1000 0000 **** 0101
原码:1000 0000 **** 0101  
反码:1111 1111 **** 1010
补码:1111 1111 **** 1011
右移3位: -5 >>> 3
-5的补码右移3位(向右移3位,左侧补30)后:0001 1111  **** 1111
右移3位后的补码:0001 1111  **** 1111
右移3位后的反码:0001 1111  **** 1111
右移3位后的原码:0001 1111  **** 1111
最终转换成10进制后: 536870911

例4 负数 -83

二进制:1000 0000 **** 0101 0011
原码:1000 0000 **** 0101 0011 
反码:1111 1111 **** 1010 1100 
补码:1111 1111 **** 1010 1101
右移3位: -83 >>> 3
右移3位(向右移3位,左侧补30)后:0001 1111 **** 0101
右移3位后的补码:0001 1111 **** 0101
右移3位后的反码:0001 1111 **** 0101
右移3位后的原码:0001 1111 **** 0101
最终转换成10进制后:1073741813

你可能感兴趣的:(日常算法积累,java)