【计算机组成原理】详细解读无符号整数的表示与运算

封面

导读

大家好,很高兴又和大家见面啦!!!

在上一篇内容中我们介绍了BCD码的相关内容:

  • BCD码是用二进制编码的十进制数,通常用4位二进制数表示一位十进制数码;
  • 8421码是一种有权码,二进制数位从高到低对应的权值为 8 、 4 、 2 、 1 8、4、2、1 8421 ;
  • 8421码在进行加法运算时,需要对无效码进行+6修正
  • 余3码是在8421码的基础上加3得到的一种无权码
  • 2421码是一种不同于8421的有权码,二进制数位从高到低对应的权值为 2 、 4 、 2 、 1 2、4、2、1 2421 ;
  • 2421码在进行加法运算时,需要对每一组无效码进行± ( 0110 ) 2 (0110)_2 (0110)2 的修正
  • 涉及到运算时,最好通过十进制数码完成运算后,再对其结果进行转码

BCD码的内容我们仅需了解即可,也不必过分深究。

在今天的内容中,我们将学习计算机中的整数的表示与运算,在学习C语言的过程中,我们知道了整数可以按照有无符号分为有符号整数与无符号整数。

从今天的内容开始,我们将会通过几章的内容来深入探讨有符号整数与无符号整数的表示方式以及运算方式。今天作为开篇,我们将会探讨相对简单的无符号整数的相关内容,接下来让咱们一起进入正题吧!!!

一、无符号整数

有符号与无符号整数对于掌握了C/C++的朋友应该是不陌生了,但是对于一些跨专业且还没有开始学习编程语言的朋友来说可能不太好理解。

下面我先给出一个最直观的理解,有符号无符号指的是数据在内存中所能够表示的数据范围。

以一个整型的数据为例,有符号整型的数据范围是 2 − 31 ~ 2 31 − 1 2^{-31}~2^{31}-1 2312311 ,而对应的无符号整型的数据范围则是 0 ~ 2 32 − 1 0~2^{32}-1 02321

1.1 无符号整型的取值范围

在C语言中,有符号整型的最大值与最小值以及无符号整型的最大值都存放在头文件<limits.h>中,我们可以通过引用头文件来获取对应的整型最值,如下所示:

无符号整型的表示
这里有朋友可能会好奇为什么最大值+1会得到最小值?

要回答这个问题,那我们就需要再回顾一下计算机结构的知识点了。

1.2 数据在内存中的存储

在计算机的硬件中,负责数据存储的是存储器这一硬件,而存储器又分为主存储器和辅助存储器。计算机系统中的存储器是主存储器,也就是我们所说的内存。

在冯·诺依曼的基本思想中,指令和数据均是由二进制代码表示,而在主存储器中,这些二进制代码都被存放在存储体中;

主存储器的工作方式是按照存储体中各个存储单元的地址进行存取,MAR就是负责寻址的寄存器,它的长度与程序计数器(PC)的长度一致,并且MAR中二进制的位数与存储体中存储单元的个数有关。

MAR的长度为8位,即能够存放8个比特位,那么对应的存储体中的存储单元的个数就是 2 8 = 256 2^8=256 28=256 个;

MDR这个寄存器则是用来存放数据的,它的长度则与存储字长相等,如当存储字长为8位时,MDR的长度也为8位,即能够存放长度为8比特位的信息,那么能够存储的整数的数据范围则是:

  • 有符号整数: − 2 7 ~ 2 7 − 1 -2^7~2^7-1 27271 − 128 ~ 127 -128~127 128127
  • 无符号整数: 0 ~ 2 8 − 1 0~2^8-1 0281 0 ~ 255 0~255 0255

当存入MDR的数据信息长度超过8个比特位时,那么多余的部分则会直接被舍弃,这样就会照成一个结果,数据会被截断,保留的是低位,舍弃的是高位。

也就是说对于256这个数据,其对应的二进制序列为: ( 1 − 0000 − 0000 ) 2 (1-0000-0000)_2 (100000000)2 存储器中能够被保留下来的是前8位二进制数,即 ( 0000 − 0000 ) 2 (0000-0000)_2 (00000000)2 ,该二进制数对应的数值为0;

而在无符号整数中,当存储的数值为最大值的情况就是对应长度中的所有二进制位都为1,在无符号整型中,对应的二进制为共32个比特位,即这32个比特位存储的数据都是1,其二进制序列为:
( 1111 − 1111 − 1111 − 1111 − 1111 − 1111 − 1111 − 1111 ) 2 (1111-1111-1111-1111-1111-1111-1111-1111)_2 (11111111111111111111111111111111)2
根据按权展开相加得到的对应数值为: 4 , 294 , 967 , 295 4,294,967,295 4,294,967,295

当我们给该数值再加上一个1后,其数值大小则变成了 4 , 294 , 967 , 296 4,294,967,296 4,294,967,296 ,该数值对应的二进制数为: ( 1 − 0000 − 0000 − 0000 − 0000 − 0000 − 0000 − 0000 − 0000 ) 2 (1-0000-0000-0000-0000-0000-0000-0000-0000)_2 (100000000000000000000000000000000)2

而该二进制数在寄存器中真正能够被存储下来的只有前面的32个比特位,即:
( 0000 − 0000 − 0000 − 0000 − 0000 − 0000 − 0000 − 0000 ) 2 (0000-0000-0000-0000-0000-0000-0000-0000)_2 (00000000000000000000000000000000)2
该二进制数对应的数值大小为0。

因此我们便得到了最大值+1为最小值的结论。该结论在有符号整型中同样适用,这个我们在后面的内容中会再详细介绍,这里就不再展开。

PS:
这里展示的二进制数之所以用'-'隔开是为了帮助大家更好的计算二进制数的长度,没有其它特别的含义。

1.3 小结

在无符号整数中,我们可以得到以下结论:

  1. 在存储字长为n的机器中,无符号整数的取值范围是: 0 ~ 2 n − 1 0~2^n-1 02n1
  2. 在无符号整数中,二进制位全为0时为最小值,二进制位全为1时为最大值;
  3. 当在存储字长为n的机器中存储长度 > n >n >n 的数据时,数据会从低位开始进行存储,并只保留前n位,超出的部分将会被舍弃,因此在无符号整数中最大值+1可以得到最小值;

现在我们对无符号整型和有符号整型有了一个初步的认识——它们的区别就是数据的取值范围不同。

那现在问题来了,在计算机中,无符号整数具体是如何进行运算的呢?下面我们接着进行探讨;

二、无符号整数的运算

在今天的内容中,我们主要探讨的是无符号整数的加法和减法是如何通过硬件实现的,对于乘法与除法,目前我们不需要去深究。下面我们就分别来看一下无符号整数的加法与减法的原理;

2.1 无符号整数的加法

无符号整数的加法实现还是比较简单的,其加法规则为:

  • 从最低位开始,按位相加,逢二进一

就比如现在我们要进行 ( 01010101 ) 2 (01010101)_2 (01010101)2 ( 00111111 ) 2 (00111111)_2 (00111111)2 这两个无符号整数的加法,其对应的运算过程如下所示:

无符号整数的运算
那具体是不是呢?下面我们通过该式子对应的十进制算式来进行验证;

根据按权展开相加法,我们不难得到:

  • ( 01010101 ) 2 = 0 × 2 7 + 1 × 2 6 + 0 × 2 5 + 1 × 2 4 + 0 × 2 3 + 1 × 2 2 + 0 × 2 1 + 1 × 2 0 = 64 + 16 + 4 + 1 = ( 85 ) 10 (01010101)_2 = 0×2^7+1×2^6+0×2^5+1×2^4+0×2^3+1×2^2+0×2^1+1×2^0=64+16+4+1=(85)_{10} (01010101)2=0×27+1×26+0×25+1×24+0×23+1×22+0×21+1×20=64+16+4+1=(85)10
  • ( 00111111 ) 2 = 0 × 2 7 + 0 × 2 6 + 1 × 2 5 + 1 × 2 4 + 1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0 = 32 + 16 + 8 + 4 + 2 + 1 = ( 63 ) 10 (00111111)_2 = 0×2^7+0×2^6+1×2^5+1×2^4+1×2^3+1×2^2+1×2^1+1×2^0=32+16+8+4+2+1=(63)_{10} (00111111)2=0×27+0×26+1×25+1×24+1×23+1×22+1×21+1×20=32+16+8+4+2+1=(63)10
  • ( 10010100 ) 2 = 1 × 2 7 + 0 × 2 6 + 0 × 2 5 + 1 × 2 4 + 0 × 2 3 + 1 × 2 2 + 0 × 2 1 + 0 × 2 0 = 128 + 16 + 4 = ( 148 ) 10 (10010100)_2 = 1×2^7+0×2^6+0×2^5+1×2^4+0×2^3+1×2^2+0×2^1+0×2^0=128+16+4=(148)_{10} (10010100)2=1×27+0×26+0×25+1×24+0×23+1×22+0×21+0×20=128+16+4=(148)10

对应的十进制数值的加法运算 ( 85 ) 10 + ( 63 ) 10 = ( 148 ) 10 (85)_{10}+(63)_{10}=(148)_{10} (85)10+(63)10=(148)10 ,因此该运算方法是正确的。

2.2 无符号整数的减法

在计算机中,当我们要实现无符号整数的减法时,实际上还是通过加法来实现的,就比如十进制算式: 8 − 5 = 8 + ( − 5 ) 8-5=8+(-5) 85=8+(5) ,为了因此为了实现减法操作,计算机会在进行减法操作时,先将减数进行特殊处理后,再通过加法规则来完成减法操作。

当我们要计算 A − B A - B AB 时, 这里需要注意的几个点是:

  1. A A A 是被减数, B B B 是减数;
  2. B B B 在进行减法操作前,需要进行全部二进制位的按位取反再加1的特殊处理
  3. 在执行减法时,实际上执行的是 A + ( ~ B + 1 ) A+(~B+1) A+(B+1) ,这里的 '~' 是C语言中的按位取反操作符

下面我们通过一组实例来进一步理解这个过程。如我们要计算 ( 10010100 ) 2 − ( 01010101 ) 2 (10010100)_2-(01010101)_2 (10010100)2(01010101)2 ,介绍加法时,我们已经介绍过了,这里实际上计算的是 ( 148 ) 10 − ( 85 ) 10 (148)_{10}-(85)_{10} (148)10(85)10 其结果应该是 ( 63 ) 10 (63)_{10} (63)10 对应的二进制数为 ( 00111111 ) 2 (00111111)_2 (00111111)2 ,下面我们就来按照实际的计算过程来验证一下:

无符号整数的运算2
可以看到运算结果是没问题的。

现在可能就有朋友好奇了,为什么计算机实现一个减法操作还需要将其转化为加法呢?

这个问题的答案仅仅是为了省钱。因为实现一个加法电路比实现一个减法电路的造价要低很多,因此仅仅通过一些处理将减法转换为加法的话,从研发成本的角度来看,可以极大的节省研发成本。

之所以在整个转化过程中是将减数进行按位取反再加一,这个问题我们目前不再继续深究,等到以后学习数论后,会再给大家进行详细的介绍。

2.3 小结

现在无符号整型的运算我们也就给大家介绍完了,下面我们简单的总结一下这块内容的知识点:

  1. 无符号整数的加法规则:从最低位开始,依次相加,逢二进一
  2. 无符号整数的减法规则:
    • 转化减数——减数按位取反再加1
    • 执行加法——被减数+(~减数+1)
  3. 将减法操作转换为加法的原因:加法电路的造价更低,能够更好的降低研发成本

结语

在今天的内容中我们介绍了无符号整数的表示与运算:

  • 无符号整数在计算机中以二进制的形式存储在内存中
  • 对于存储子长为n的机器来说,能够存储的无符号整数的数值范围为: 0 ~ 2 n − 1 0~2^n-1 02n1
  • 当存储长度超过存储长度的数据时,前n位将会被保留,超出的高位部分将会被舍弃
  • 无符号整数的加法与减法都是以加法的形式实现
  • 无符号整数的加法规则:从最低位开始,依次相加,逢二进一
  • 无符号整数进行减法时,需要将减数进行按位取反再加1的转化

今天的内容到这里就全部结束了,在下一篇内容中我们将介绍《有符号整数》的相关内容,大家记得关注哦!如果大家喜欢博主的内容,可以点赞、收藏加评论支持一下博主,当然也可以将博主的内容转发给你身边需要的朋友。最后感谢各位朋友的支持,咱们下一篇再见!!!

  • 9
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值