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

2024-09-06 11:12

本文主要是介绍【计算机组成原理】详细解读无符号整数的表示与运算,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

定点数的编码表示与运算

  • 导读
  • 一、无符号整数
    • 1.1 无符号整型的取值范围
    • 1.2 数据在内存中的存储
    • 1.3 小结
  • 二、无符号整数的运算
    • 2.1 无符号整数的加法
    • 2.2 无符号整数的减法
    • 2.3 小结
  • 结语

封面

导读

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

在上一篇内容中我们介绍了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的转化

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

这篇关于【计算机组成原理】详细解读无符号整数的表示与运算的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1141841

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

java程序远程debug原理与配置全过程

《java程序远程debug原理与配置全过程》文章介绍了Java远程调试的JPDA体系,包含JVMTI监控JVM、JDWP传输调试命令、JDI提供调试接口,通过-Xdebug、-Xrunjdwp参数配... 目录背景组成模块间联系IBM对三个模块的详细介绍编程使用总结背景日常工作中,每个程序员都会遇到bu

MySQL之搜索引擎使用解读

《MySQL之搜索引擎使用解读》MySQL存储引擎是数据存储和管理的核心组件,不同引擎(如InnoDB、MyISAM)采用不同机制,InnoDB支持事务与行锁,适合高并发场景;MyISAM不支持事务,... 目录mysql的存储引擎是什么MySQL存储引擎的功能MySQL的存储引擎的分类查看存储引擎1.命令