二进制数

。为此,在表示负数时就需要使用“二进制的补码”。补码就是用正数来表示负数

负数

  • 对于有符号正数,一般将最高位作为符号位,1表示负数,0表示正数
  • 计算机在做减法运算时,实际上内部是在做加法运算。即加上一个负数
  • 负数是用正数的补码表示的,而不是将正数的符号位0直接改成1,如果符号位为1,那么这个数是负数,且是用正数的补码表示的

补码

  • 将二进制数的各数位的数值全部取反,然后再将结果加1
  • $-A$的补码为$A$
  • 可以用负数的补码来求相反数即正数
推导

$$ \begin{align} max + 1 &= 0 \ 原码 + 原码各数位取反 + 1 &= 0 \ 原码 + 补码 &= 0 \ \end{align} $$

表示范围

int16举例,表示范围为$[-2^{15}, 2^{15}-1]$,共$2^{16}个数$。负数为$[-2^{15}, -1]$共$2^{15}$个数,正数为$[1, 2^{15}-1]$共$2^{15}$个数

看起来负数好像表示范围比正数多1个,因为0000000000000000表示0,而1000000000000000则是用补码表示的负数,其相反数(可用补码即所有数位取反后加1求出来)是1000000000000000即$2^{15}$,也就是说1000000000000000表示$-2^{15}$。两者相加后最高位进位(更高位被舍弃)因此结果是0,这两者确实是互为相反数

位移

左移

直接将所有数位左移,在剩下的数位上补0即可

  • 正数:每个数位的1都进位了1,因此所表示的值都翻倍了
  • 负数: 如果符号位的右一位不是0,说明这个负数再左移(翻倍)一次就必定会超过表示范围,从而造成不可预料的结果 反之如果左移后仍在表示范围内(恰好,其相反数即正数也在表示范围内),则符号位的右一位必定也是1。此时可以换一种思路,先通过补码转成正数,再左移1位,再通过补码变回负数,至于符号位当然要保持为1不变来表示负数,而符号位的右一位1左移后刚好作为表示负数的符号位1。具体可自行验证
右移

将所有数位右移,然后在剩下的数位上补上和符号位相同的数

为什么相比左移多了判断符号位的步骤?

比如将-4右移1位变为-2,可以先通过补码(按位取反再加1)变为4,然后4右移1位变为2,再通过补码变为-2,在这些过程中,并不会改变符号(正负),因此正数要补0,负数要补1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值