有符号数的二进制表示法、加减法、补码

您所在的位置:网站首页 二进制的算数减 有符号数的二进制表示法、加减法、补码

有符号数的二进制表示法、加减法、补码

2024-07-14 00:00| 来源: 网络整理| 查看: 265

转载:http://blog.sina.com.cn/s/blog_6f5a79c90102w62s.html

有符号数的表示法、加减法、补码

摘要:本文将会说明有符号数的表示方法,有符号数正负数之间的跳变,有符号负数的加减法,为什么采用补码等方面进行分析。

我是学过计算机原理的,也有有符号数和无符号数的概念,以及正码、反码、补码的概念。可是我今天在看C++primer plus时仍然对讲解的有符号数之间的跳变搞蒙了。原因是我只是有了概念,当初学习没有深入的去问为什么计算机会这么处理有符号的数据。那么好吧,现在就得补回来。

有符号数

有符号数的概念当然就是,用一个比特表示正负了,很明显是这样,比如:+8为00001000,-8就是10001000(这里呢就用8位的长度表示数值),可见在+8和-8的二进制有符号表示的时候差别就在首位字节,就是第一个比特了。这就是有符号数。

为什么要用有符号数?

我想应该是数学逻辑中就是有正负的,而计算机作为数据处理的工具当然要可以表示数据的正负,所以这是很显然的事情。

有符号数带来的问题

正负的表示问题我们是解决了,可是光表示了是不行的,我们的目的还是用来运算的。那么问题来了。

引入了一个符号位,其表示数值的范围是多少?

8位的数据的二进制范围是,00000000-11111111,即十进制的0-255,。有符号数的首位可是有含义的,所以二进制仍然是00000000-11111111,但是十进制的范围就成了,-128-+127,就是-128到+127,然而这是有问题的,什么问题?有没有想过0该这么表示,10000000(-0)还是00000000(+0)。这的确是个问题,如果有了正负0那么取值的范围很明显就是-127到+127了嘛,中间有两个正负0。当然严谨的计算机科学家是不允许的,所以只能有一个表示十进制的0,那就是00000000,可是10000000表示个啥?规定表示为-128,这样就解决了两个0的问题,而且取值的范围就是-128到+127。

有符号数之间的跳变?

什么事跳变,其实就是溢出,什么又是溢出,其实就是数值的超出了范围。举个例子,8位有符号数范围我们是知道了就是-128到+127,但是当我超出了+127时会怎样?看一下

+127

+  1

------

=+128

十进制来看是这样的,但是+128已经超出了表示的范围了。那么跳变就出现了。通过二进制看一下

 01111111(+127)

+00000001(  +1)

----------------

=10000000(-128)

二进制相加的结果是10000000,从前面的定义我们知道它是-128。这就是溢出了,发生了跳变。在工程中我们一定要避免这种事情的,因为它不是我们期望的数值。所以搞清楚每个类型的取值的范围是必要的。

 这种跳变我不知道工程中会不会用到,但是我是不想用到的,因为不符合常规逻辑。

有符号数的加法

前面也用到了有符号数的加法,在正数时,不超过+127范围时还是正常的,该是几就是几。超出就是负数了,那么我们讨论一下负数的加法。

先说-128吧。

 (-128)

+  (+1)

---------

=-127

没毛病,十进制是这样的。二进制又是这么样的?

 10000000(-128)

+00000001  (+1)

----------------

=10000001(-1)

以下是重点

结果怎么是这样呢?怎么会是-1而不是-127呢?跟我想的不一样,很不开心。可是不开心是没有用的,我们仍然要解决问题。怎么解决?

1、改变加法器。因为正数的加法器不适用于负数的加法运算。这是一个方案,可是这会导致正数和负数用了两个加法器,如果硬件做加法,那就会增加电路负担,有没有可以通过软件解决的?

2、改变表示方式。什么意思?就是说-128在计算机中并不是用10000000存储,而是其他的,怎么表示呢?把负数表示成什么0减去一个正数?试试看

-128为0-128,100000000(9位,理解为向第9位借了一位1)-10000000=11111111+00000001-10000000=100000000

-127为0-127,100000000(9位,理解为向第9位借了一位1)-01111111,即11111111+00000001-01111111=10000001

这样看起来真是是对的了!这样为什么是可以的?

1、两边是恒等式,因为两边都有向第9位借了1位,其实就是两边都加了一个数。即,

-128+1=-127可以表示为(256-128)+1=(256-127),二进制表示为

[(11111111+00000001)-10000000]+00000001=[(11111111+00000001)-01111111]=10000001。

2、这样做其实是把有符号数转变成了无符号数的运算,即把-128转换为了无符号数10000000,注意这里其实并不是-128。我想表达的意思是在运算的时候不要把首位比特当做字符了。其实在转换的时候用到减法运算,这样的目的呢就是在数值上不区分正负,而在转换的运算符中考虑了。所以会是这样。

 其实这个转换呢就是补码,这是我参考了别的博文,自己理解的补码的由来,很多教科书都会将到补码的计算公式,然而却并不去讲这个的由来,大多数学生也都是选择了死记硬背,先记住再说,然后就没有再说了,这样真的不好。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3