原码、反码、补码、移位、运算符&|


以下均以byte类型存储8位为例

原码

5 0000 0101

-5 1000 0101

首位是符号位,0表示正,1表示负

反码

5 0000 0101

-5 1111 1010

正数的反码是本身

负数的反码是除了符号位,其余位取反;

补码

5 0000 0101

-5 1000 1011

正数的补码是本身

负数的补码是它的反码加1

移位

以下出现的二进制都是原码

5 << 1 即 0000 1010 即 10 = 5 * 2

5 << 2 即 0001 0100 即 20 = 5 * 2 * 2

5 >> 1 即 0000 0010 即 2 (丢失精度)

6 >> 1 0000 0110 移位后 0000 0011 即 3 = 6 / 2

-5 << 1 即 1000 1010 即 -10 = -5 * 2

-5 << 2 即 1001 0100 即 -20 = -5 * 2 * 2

-5 >> 1 即 1000 0010 即 -2 (丢失精度)

-6 >> 1 1000 0110 移位后 1000 0011 即 -3 = -6 / 2

正数移位时,左移n位,得到的结果是原来的值乘以2的n次方,右移是除以2的n次方,有时会出现丢失精度。

负数与正数的区别是首位的符号位不动。

负数的补码进行移位时,左移则右边补0,右移则左边补1。

运算符& 、|

&(念做与)、|(念做或)

1010&0110=0010

1010|0110=1110

&表示必须两个都是1,结果才是1,否则是0

|表示只要有一个0,结果就是0,否则是1

思考

补码的作用

在计算机进行二进制计算时,如果两个数字的符号位不同,则需要先进行取绝对值得到两个数中较大的那个,然后将大数减去小数,结果的符号以大数为准。过程较为复杂,那么如果可以只用加法运算来替换减法运算,则会提升很多效率。

通过对负数取补码,然后和正数进行加法运算。所以计算机中的负数是都是以补码的形式存储。

为什么负数的补码是原码按位取反再加一?

以钟表为例,指向6为基础,顺时针转动为正,逆时针转动为负

若要指针指向3,需要顺时针转动9(+9),6+9=15

也表示逆时针转动3(-3),6-3=3

以12为模,15-12=3 = 6-3=3,就是说15和3表示的含义是一样的,都表示3点,所以-3和+9是互为补数的。计算方式为模-数,即12-3=9,-3的补数就是9。

在二进制时,模是2,-1001与+0111是互为补数的,计算方式为2(0010)-1001=0111,由此可以得出:在二进制中,负数的补码是原码按位取反,再加1。

反码的作用

反码的主要作用就是原码求补码的中间过渡

应用场景

在jdk1.8中的HashMap.java,默认初始容量使用了移位

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

该类中也存在多处使用到&、|运算

if ((first = tab[i = (n - 1) & hash]) != null) {

进行该种运算时,需要先根据负数求出补码,再与正数计算。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值