计算机的二进制数

计算机如何存储数据

计算机都是用二进制存储数据,这些二进制数值有两种格式表示:无符号数和有符号数。

  • 无符号数:无符号数就是没有正负号之分,只有0和正数;所有位数都表示数值。
  • 有符号数:有符号数有正负号之分,有负数、0、正数;在最高位0表示正数,1表示负数,除开最高位的符号位,剩下的值才表示具体数值。

以一个字节举例,byte=1个字节 = 8bit(位):

  • 无符号数能表示的范围是:0~255。
  • 有符号数能表示的范围是:-128~127。

什么是原码

原码(true form)是一种计算机中对数字的二进制定点表示方法。数值最高位表示符号位:正数该位记为0,负数该位记为1(0有两种表示:+0和-0),其余位表示数值的大小。

举例:10进制的数值2和-2,我们用2进制来表示:

  1. byte存储分别为:0000 00101000 0010;byte=1个字节 = 8bit(位)。
  2. int存储分别为:0000 0000 0000 0000 0000 0000 0000 00101000 0000 0000 0000 0000 0000 0000 0010;int =4个字节=32bit(位)。

可以看出byte扣除了最高位的符号位,只剩7位二进制数能表示数值。它的最大值为:0111 1111,最小值为:1000 0000这里其实用的是补码),即byte只能表示-128~127。

思考:

  1. 为什么最小值不是1111 1111-127,而是1000 0000-128?
  2. 为什么1000 0000不是表示-0,而表示-128?

让我们带着问题继续往下阅读。

什么是反码

反码的表示方法是:正数的反码是其本身;负数的反码是在其原码的基础上, 符号位不变,其余各个位取反。

举例:

  1. 10进制 1,原码:0000 0001,反码:0000 0001
  2. 10进制-1,原码:1000 0001,反码:1111 1110

什么是补码

补码的表示方法是:正数的补码就是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1(即在反码的基础上+1)。

举例:

  1. 10进制 1,原码:0000 0001,反码:0000 0001,补码:0000 0001
  2. 10进制-1,原码:1000 0001,反码:1111 1110,补码:1111 1111

原码、反码、补码意义

问题

  1. 原码更容易被人直接识别并用于计算的表示方式,为何还会有反码和补码呢?
  2. 那么在计算机中的二进制数值,是以什么方式存储的?

:虽然人脑更容易识别原码、计算原码,但是计算机的二进制数值却是以补码的方式存在的,最终转换成原码给我们呈现。

具体分析
这样存储的好处是避免的0的编码有两个,0000 0000原码和1000 0000原码都表示0,-0和+0;
并且,对于计算机来说,辨别"符号位"显然会让计算机的基础电路设计变得十分复杂。符号位和具体数值值位可以一起处理,减法通过加法就可以实现:1-1 = 1 + (-1) = 0,这样简化了计算机的结构设计,同时也提高了运算速度。

  • 首先来看原码的减法计算:
    1 - 1 = 1 + (-1) =
    0000 0001原码 + 1000 0001原码 =
    1000 0010原码 = -2
    如果用原码表示,让符号位也参与计算,显然对于减法来说结果是不正确的,这也就是为何计算机内部不使用原码表示一个数。

  • 为了解决原码做减法的问题,我们使用反码计算:
    1 - 1 = 1 + (-1) =
    0000 0001原码 + 1000 0001原码=
    0000 0001反码 + 1111 1110反码 =
    1111 1111反码 =
    1000 0000原码 = -0

可以看到,我们用反码计算减法,结果的非符号位部分是正确的。唯一的问题出在于"0"这个特殊的数值上。虽然人们理解上+0和-0是一样的,但再计算机中0带符号是有意义的,并不是说0000 0000原码和1000 0000原码都表示0。

  • 最后我们用补码计算:
    1-1 = 1 + (-1) =
    0000 0001原码 + 1000 0001原码 =
    0000 0001补码 + 1111 1111补码 =
    0000 0000补码(此时的补码数值,最高位已经到第九位,溢出被截断,只保留8位)=
    0000 0000原码=0

我们用0000 0000表示0,就不会出现-0的情况了,并且我们就可以用 1000 0000表示-128,如下公式所示:
(-1) + (-127) =
1000 0001原码 + 1111 1111原码 =
1111 1111补码 +1000 0001原码 =
1000 0000补码=-128
我们用以前的-0的补码来表示-128,所以-128并没有原码和反码表示。byte的取值范围是-128~127[-27, 27-1],你明白了吗?

举一反三:
32位的int表示范围:[-231, 231-1],即二进制表示范围:1000 0000 0000 0000 0000 0000 0000 0000~0111 1111 1111 1111 1111 1111 1111 1111

深入思考

我们只说明了补码的计算,但这个规律是怎么发现的?这里面蕴含怎样的数学原理,这就触及到我的知识盲区了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值