反码补码原码笔记(不断更新)

1 原码反码补码的转换

1000 0000 0000 0000 0000 0000 0001 0100 原码
1111 1111 1111 1111 1111 1111 1110 1011 反码
1111 1111 1111 1111 1111 1111 1110 1100 补码(反码变补码,+1
1111 1111 1111 1111 1111 1111 1011 0000 左移两位,低位补0
1111 1111 1111 1111 1111 1111 1010 1111 反码(补码变反码,-1
1000 0000 0000 0000 0000 0000 0101 0000 原码
2^6 + 2^4 = 64 + 16 = 80,高位为1,代表负数,就是-80
总结:原码到补码和补码到原码都是取反再加1, 同时补码到原码也可以先减一再取反

2 符号扩展位转换的原因

把一个二进制数右移N位,规则为:
除符号位外,全部右移N位,
如果数字是一个无符号数值,则用0填补最左边的N位,
如果数字是一个有符号数值,则用1填补最左边的N位,

也就是说如果数字原先是一个正数,则右移之后在最左边补N个0;如果数字原先是个负数,则右移之后在最左边填补N个1。

例子:
0000 0010 >> 1 = 0000 0001
0000 1010 >> 2 = 0000 0010
1000 0010 >> 1 = 1100 0001
1000 1010 >> 3 = 1111 0001

上面的例子,正数的容易理解,为什么负数的是填补N个1呢,解释如下:
负数在计算机内部是以补码形式存放的,同样,正数也是以补码形式,只不过正数的补码和原码一样。即数据在计算机中是以补码的形式存储的,所以一般所指“二进制”为数的补码表示
1000 0010是一个负数,它的原码是1111 1110,(原码、反码、补码怎么转换自行百度),也就是说它不是表示-2,而是表示-126;
怎么证明1000 0010右移1位后是1100 0001呢,
1000 0010的原码是1111 1110,对原码右移1位,为1011 1111,(也就是-63),再换成补码,为1100 0001,
可以看出,1000 0010右移1位确实是1100 0001,也就是说,

如果数字原先是个负数,则右移之后在最左边填补N个1。

上面的例子是移位出来结果是整数,不用四舍五入的,下面例子是需要四舍五入的。
1000 1010 的原码1111 0110(-118),右移三位1000 1110(-14)。实际结果为(-118/8=-14.75)。按照符号位扩展得到的补码1111 0001对应的原码是1000 1111(-15),更接近实际值。可以看到符号位扩展的优越性:即符号扩展位移位很接近于实际值

3 左移,符号位扩展右移,无符号右移

首先左移和右移的区别是很好区分的

左移<< :就是该数对应二进制码整体左移,左边超出的部分舍弃,右边补零。举个例子:253的二进制码1111 1101,在经过运算253<<2后得到1111 0100。很简单
右移>> :该数对应的二进制码整体右移,左边的用原有标志位补充,右边超出的部分舍弃。
无符号右移>>> :不管正负标志位为0还是1,将该数的二进制码整体右移,左边部分总是以0填充,右边部分舍弃。
举例对比:
-5用二进制表示1111 1011,斜体为该数标志位
-5>>2: 1111 1011-------------->1111 1110。
11为补充标志位
-5>>>2: 1111 1011-------------->0011 1110。
00为补充的0

4 负数左移右移运算(都是补码在左、右移)

1)负数的右移:负数右移的话,由于要保持它是负数,所以负数的二进制的右边补1。如果一直右移的话,最后就就变成0xFFFFFFFF 即-1
如: -4>>1 为-2 ;-4>>2为-1
2)负数的左移:跟正整数左移一样,右边补0,一直左移的话,最后就是0啦。-2<<2 为-4 ; -2<<31为0
如-4(1000 0100),其补码为1111 1100,>>1的结果是1111 1110,对应原码是1000 0010(-2);<<2的结果1111 0000,对应原码1001 0000(-16)
再给一个溢出例子:-16378<<2 -16378的原码是1011 1111 1111 1010,对应的补码是1100 0000 0000 0110,<<2是通过补码左移,为0000 0000 0001 1000,这时计算机看到是正数,所以原码也是这个,即24

5 举例

对于带符号右移,若为负数,则在存储时首位表示符号位,其值为1,表示该值是负数的移位,在移位过程中,高位补1,若符号位是0,表示是正数,在移位过程中高位补零,两者的前提是符号位保持不变:

    对于负数的右移:因为负数在内存中是以补码形式存在的,所有首先根据负数的原码求出负数的补码(符号位不变,其余位按照原码取反加1),然后保证符号位不变,其余位向右移动到X位,在移动的过程中,高位补1.等移位完成以后,然后保持符号位不变,其余按位取反加1,得到移位后所对应数的原码。即为所求。

   举例1:

               -100带符号右移4位。

               -100原码:   10000000    00000000    00000000   01100100

               -100补码:    保证符号位不变,其余位置取反加1

                                     11111111    11111111    11111111   10011100

               右移4位   :   在高位补1

                                     11111111    11111111    11111111    11111001

                             补码形式的移位完成后,结果不是移位后的结果,要根据补码写出原码才是我们所求的结果。其方法如下:

                保留符号位,然后按位取反

                                     10000000    00000000    00000000     00000110

                然后加1,即为所求数的原码:

                                               10000000    00000000    00000000    00000111

                     所有结果为:-7

              举例2:

                        -100无符号右移4位。

               -100原码:   10000000    00000000    00000000   01100100

               -100补码:    保证符号位不变,其余位置取反加1

                                     11111111    11111111    11111111   10011100

               无符号右移4位   :   在高位补0

                                     00001111    11111111    11111111    11111001

              即为所求:268435449

总结:正数的左移与右移,负数的无符号右移,就是相应的补码移位所得,在高位补0即可。 负数的右移,就是补码高位补1,然后按位取反加1即可。

引用的经典笔记

经典笔记

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值