计算机原码、补码、反码与java移位运算符(<</>>/>>>)

一、机器值和真值

1.机器值

一个数在计算机中的二进制表示形式,  叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1。

比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。

那么,这里的 00000011 和 10000011 就是机器数。

2.真值

因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。

例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1

3.原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值。原码取值范围:【11111111,011111111】即【-127,127】

4.反码

正数的反码是其本身。

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。

[+1] = [00000001] = [00000001]

[-1] = [10000001] = [11111110]

5.补码

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001] = [00000001] = [00000001]

[-1] = [10000001] = [11111110] = [11111111]

深入了解

注:

  1. 机器都是使用补码,运算也是使用补码。
  2. 正数的原码、补码、反码都一样。
  3. 补码与原码相互转换,其运算过程是一样的。

1.左移运算符

左移的规则只记住一点:丢弃最高位,0补最低位

左移一位相当于乘以2的1次方,左移n位就相当于乘以2的n次方。

运算方式:数值的补码全部往左移动X位,符号位和最高位都舍弃,最低位补0。

正数:
int a = 5 ;
int b = a << 2 ;(5*22=20)
[ 0000 0000 0000 0000 0000 0000 0000 0101 ] 5的补码
[ 0000 0000 0000 0000 0000 0000 0001 0100 ] 对于正数而言,反码就是原码,即 20

负数:
int a = -5 ;
int b = a << 2 ;(-5*22=-20)
[ 1000 0000 0000 0000 0000 0000 0000 0101 ] -5的原码
[ 1111 1111 1111 1111 1111 1111 1111 1010 ] -5的反码
[ 1111 1111 1111 1111 1111 1111 1111 1011 ] -5的补码
[ 1111 1111 1111 1111 1111 1111 1110 1100 ] a<<2左移2位
将补码转换成原码就可以得到数值,补码转原码和原码转补码一样,符号位不变,其余位取反加一。
[ 1000 0000 0000 0000 0000 0000 0001 0011 ]
[ 1000 0000 0000 0000 0000 0000 0001 0100 ] 得到a<<2的原码,即 -20

2.右移运算符

右移的规则只记住一点:符号位不变,左边补上符号位。

右移一位相当于除以2的1次方,右移n位就相当于除以2的n次方。

运算方式:数值的补码向右移X位,符号位不变(左边补上符号位)。

与左移差不多,这里就不列出具体案例了。

3.无符号右移

无符号右移的规则只记住一点:忽略了符号位扩展,0补最高位

无符号右移规则和右移运算是一样的,只是填充时不管左边的数字是正是负都用0来填充,无符号右移运算只针对负数计算,因为对于正数来说这种运算没有意义

用移位操作可以极大地提高性能,因为在计算机底层对位的操作是最快。

链接

有些是自己写的,有些是COPY的,方便以后的查看。

猜你喜欢

转载自www.cnblogs.com/LovelyAnimal/p/10316775.html