一、涉及到的5个基础知识:
- 1.有符号的整数,二进制最高位是符号位,正数符号位是0,负数符号位是1
- 2.反码定义:正数的反码与原码相同,负数的反码等于原码除符号位外各位取反
- 3.补码定义:正数的补码与原码相同,负数的补码等于反码加1,并保持符号位不变
- 4.人为将二进制转换十进制的方法:
(1)通过原码方式:
JAVA中正整数**7**的二进制原码:00000000 00000000 00000000 00000111
转换成十进制:1*(2的2次方)+1*(2的1次方)+1*(2的0次方)=4+2+1=7
JAVA中负整数**-7**的二进制原码:10000000 00000000 00000000 00000111
转换成十进制:-(1*(2的2次方)+1*(2的1次方)+1*(2的0次方))=-(4+2+1)=-7
(2)通过补码方式:
JAVA中正整数**7**的二进制补码(与原码相同):00000000 00000000 00000000 00000111
转换成十进制:0+ 1*(2的2次方)+1*(2的1次方)+1*(2的0次方)=4+2+1=7
JAVA中负整数**-7**的二进制补码:11111111 11111111 11111111 11111001
转换成十进制: -1*(2的31次方)+1*(2的30次方)+1*(2的29次方)+...+1*(2的3次方)+0*(2的2次方)+0*(2的1次方)+1*(2的0次方)=-7
- 5.计算机使用 补码 存储和运算带符号整数
(1)比如1+1,对于计算机来说是以下运算:
1的补码 00000000 00000000 00000000 00000001
+
1的补码 00000000 00000000 00000000 00000001
=
结果 00000000 00000000 00000000 00000010
结果是补码:00000000 00000000 00000000 00000010
最高位是0表示正数,所以原码与补码相同,
转换为10进制为: 1*2^1 + 0*2^0 = 2 + 0 =2
(2)比如1-2,对于计算机来说是以下运算(即1+(-2)):
1的补码 00000000 00000000 00000000 00000001
+
-2的补码 11111111 11111111 11111111 11111110
=
结果 11111111 11111111 11111111 11111111
结果是补码:11111111 11111111 11111111 11111111
最高位是1表示负数,可以通过反向操作,得出反码11111111 11111111 11111111 11111110,
然后再通过反码得出原码10000000 00000000 00000000 00000001
再通过原码转为十进制: -(0*2^1)=-1
或者直接通过补码结果转换为10进制为:-1*2^31+1*2^30+1*2^29+...1*2^1+1*2^0=-1
二、JAVA的位移运算 << 、>>、>>>
1.带符号左移<<,无论正负数,低位空出来的均补0,a<<n从十进制结果上看就是原值a乘以2^n
正数案例:
例如: 7<<2的运算过程
7的补码: 00000000 00000000 00000000 00000111
7左移2位: 00000000 00000000 00000000 00000111
低位补0: 00000000 00000000 00000000 0000011100
去掉高位多余2位: 00000000 00000000 00000000 00011100
结果是补码00000000 00000000 00000000 00011100
原码也是00000000 00000000 00000000 00011100
转换为十进制是1*2^4+1*2^3+1*2^2=16+8+4=28
负数案例:
例如: -7<<2的运算过程
-7的原码: 10000000 00000000 00000000 00000111
-7的反码: 11111111 11111111 11111111 11111000
-7的补码: 11111111 11111111 11111111 11111001
-7左移2位: 11111111 11111111 11111111 11111001
低位补0: 11111111 11111111 11111111 1111100100
去掉高位多余2位: 11111111 11111111 11111111 11100100
结果是补码11111111 11111111 11111111 11100100
还原反码是11111111 11111111 11111111 11100011
还原原码是10000000 00000000 00000000 00011100
转换为十进制是-(1*2^4+1*2^3+1*2^2)=-(16+8+4)=-28
2.带符号算术右移>>,正数高位空出来的补0,负数高位空出来的补1, a>>n从十进制结果上看:正数相当于a除以2^n向下取整;负数相当于a的绝对值除以 2^n向上取整后的负数。
正数案例:
例如: 7>>2的运算过程
7的补码: 00000000 00000000 00000000 00000111
7右移2位: 00000000 00000000 00000000 00000111
高位补0: 0000000000 00000000 00000000 00000111
去掉低位多余2位: 00000000 00000000 00000000 00000001
结果是补码00000000 00000000 00000000 00000001
原码也是00000000 00000000 00000000 00000001
转换为十进制是1
负数案例:
例如: -7>>2的运算过程
-7的原码: 10000000 00000000 00000000 00000111
-7的反码: 11111111 11111111 11111111 11111000
-7的补码: 11111111 11111111 11111111 11111001
-7右移2位: 11111111 11111111 11111111 11111001
高位补1: 1111111111 11111111 11111111 11111001
去掉低位多余的2位: 11111111 11111111 11111111 11111110
结果是补码11111111 11111111 11111111 11111110
还原反码是11111111 11111111 11111111 11111101
还原原码是10000000 00000000 00000000 00000010
转化为十进制是 -(1*2^1) = -2
3.无符号逻辑右移>>>,无论正负数,高位空出来的均补0,从十进制结果都是正数;对于正数来说>>>和>>是一样的,但是对于负数来说不一样,负数的>>高位补1,负数的>>>高位补0。
正数案例:
例如: 7>>>2的运算过程
7的补码: 00000000 00000000 00000000 00000111
7右移2位: 00000000 00000000 00000000 00000111
高位补0: 0000000000 00000000 00000000 00000111
去掉低位多余2位: 00000000 00000000 00000000 00000001
结果是补码00000000 00000000 00000000 00000001
原码也是00000000 00000000 00000000 00000001
转换为十进制是1
负数案例:
例如: -7>>>2的运算过程
-7的原码: 10000000 00000000 00000000 00000111
-7的反码: 11111111 11111111 11111111 11111000
-7的补码: 11111111 11111111 11111111 11111001
-7右移2位: 11111111 11111111 11111111 11111001
高位补0: 0011111111 11111111 11111111 11111001
去掉低位多余的2位: 00111111 11111111 11111111 11111110
结果相当于正数补码00111111 11111111 11111111 11111110
原码与补码相同是00111111 11111111 11111111 11111110
转化为十进制是 1*2^29+1*2^28+1*2^27+...+1*2^1+0*2^0 = 1073741822