【CSAPP/计组】#1 数的存储与表示方法、机器中浮点数加减法详解

文章目录

  • 前言
  • 一、定点格式
    • 定点整数
  • 二、浮点数的表示方法
    • 2.1 浮点数存储
    • 2.2 浮点数加减法
      • a. 操作数检查
      • b. 对阶
      • c. 尾数相加与检查溢出
      • d. 结果规格化与溢出处理
      • e.舍入处理
    • Some tips: 为什么进位/双符号判断法有效的通俗解释?
    • Some tips:符号位拓展


前言

计算机中常用的数据表示格式有两种,一是定点格式,二是浮点格式。一般来说,定点格式容许的数值范围有限,要求的处理硬件比较简单。而浮点格式容许的数值范围很大,要求的处理硬件比较复杂。


一、定点格式

所谓定点格式,即约定机器中所有数据的小数点位置是固定不变的。由于约定在固定的位置,小数点就不再使用记号“.”来表示。原理上讲,小数点位置固定在哪一位都可以,但是通常将数据表示成纯小数纯整数

目前计算机中多采用定点纯整数表示,因此将定点数表示的运算简称为整数运算

定点整数

  • 一个正整数,当用原码、反码、补码表示时,符号位都固定为 0,用二进制表示的数位值都相同,即三种表示方法完全一样。
  • 一个负整数,当用原码、反码、补码表示时,符号位都固定为 1,用二进制表示的数位值都不相同。此时由原码表示法变成补码表示法的规则如下:
    (1)原码符号位为 1 不变,整数的每一位二进制数位求反得到反码;
    (2)反码符号位为 1 不变,反码数值位最低位加 1,得到补码。

该种表示方法优点:

  • 很好地使得+0与-0都为唯一格式存储
  • 使得相同的的硬件用同样的方式可以同时处理加减法(减法看做正负数相加)
    eg:
    在这里插入图片描述

具体数学原理不在此赘述。

二、浮点数的表示方法

计算机中,把一个数的有效数字数的范围在计算机的一个存储单元中分别予以表示。这种把数的范围和精度分别表示的方法,相当于数的小数点位置随比例因子的不同而在一定范围内可以自由浮动,所以称为浮点表示法。

规定:任意一个十进制数 N 可以写成 N = 10^E . M
同样,在计算机中一个任意二进制数 N 可以写成 N = 2^e . MM 称为浮点数的尾数,是一个纯小数。e 是比例因子的指数,称为浮点数的指数,是一个整数。

2.1 浮点数存储

IEEE754标准规定的 32 位短浮点数和 64 位长浮点数的标准格式,同时规定移码的偏置值是 2^(n-1)-1

在这里插入图片描述

  • 由于基数 2 是固定常数,对每一个浮点数都一样,所以不必用显示表达(存储)它。
  • 32 位的浮点数中,S 是浮点数的符号位,占 1 位,安排在最高位,S=0 表示正数,S=1表示负数。M 是尾数,放在低位部分,占用 23 位,小数点位置放在尾数域最左(最高)有效位的右边。E 是阶码,占用 8 位,阶符采用隐含方式,即采用移码方法来表示正负指数。采用这种方式时,将浮点数的指数真值 e 变成阶码 E 时,应将指数 e 加上一个固定的偏置常数 127,即 E=e+127这种表示方法的好处是E可表示的数恒大于0(可看做为无符号数),便于比较不同数字之间的阶码大小
  • 64 位的浮点数中符号位 1 位,阶码域 11 位,尾数域 52 位,指数偏移值是 1023。
  • 为了提高数据的表示精度,当尾数的值不为 0 时,尾数域的最高有效位应为 1,这称为浮点数的规格化表示

所以在 IEEE754 标准中,一个规格化的 32 位浮点数 x 的真值表示为
x=(–1)S×(1.M)×2E–127, e=E–127
规格化的 64 位浮点数 x 的真值为 x=(–1)S×(1.M)×2E–1023, e=E–1023

对于单精度,最大的指数为127(0+127),最小的指数为-126(-255+127);

规格化的浮点数的尾数域最左位(最高有效位)总是 1,故这一位无需存储,而认为隐藏在小数点的左边。于是用 23/52 位字段可以存储 24/53 位有效数

对 32 位浮点数 N,IEEE754 定义一些特殊情况(N为真值):

  • 若 E=255 且 M!=0,则 N=NaN符号 NaN (Not a Number)表示无定义数据,采用这个标志的目的是让程序员能够推迟进行测试及判断的时间,以便在方便的时候进行。
  • 若 E=255 且 M=0,则 N=(–1)S。当阶码 E 为全 1 且尾数 M 为全 0 时,表示的真值 N 为无穷大,结合符号位 S 为 0 或 1,也有+∞和–∞之分。
  • 若 0<E<255,则 N=(–1)S×(1.M)×2E–127(规格化数)。偏移值不选27=128(10000000),而选 27–1= 127(01111111)。阶码 E 的范围变为 1~254,指数值 e 则为–126~+127。因此 32 位浮点数表示的绝对值的范围是 10–38~1038。
  • 若 E=0 且 M=0,则 N=(–1)S0。当阶码 E 为全 0 且尾数 M 也为全 0 时,表示的真值N 为零(称为机器 0),结合符号位 S 为 0 或 1,有正零和负零之分。
  • 若 E=0 且 M!=0,则 N=(–1)S×(0.M)×2–126(非规格化数)。对于规格化无法表示的数据,可以用非规格化形式表示。(下图符号表述与本文有些不同,注意区分)在这里插入图片描述

2.2 浮点数加减法

a. 操作数检查

  • 若有一个操作数为NaN则直接返回NaN
  • 若有一个操作数为0则直接返回另一个操作数
  • 若有一个操作数为Infinity:
    • 若另一个操作数也是Infinity且符号相同则返回第一个操作数
    • 若另一个操作数也是Infinity且符号不同则返回NaN
    • 若其他情况则返回Infinity

b. 对阶

两操作数可直接进行加减操作的前提是两者同阶。因此需要对不同阶的操作数进行小数点对齐,由于存储的尾数在右移的过程中损失精度的概率比左移要小(因为尾数的存储时未使用的位数是在有效位右边补0),所以我们采取小阶向大阶对齐
注意这里的阶码e指的是该数字在规格化二进制下的阶码,或者无法规格化时的阶码

For example:
0.65的32位存储 其阶码e实际为Exp-127=126-127=-1
在这里插入图片描述
-0.425的32位存储 其阶码e实际为Exp-127=125-127=-2
在这里插入图片描述
此时我们如果要对两者进行操作,就需要将-0.425二进制存储的尾数右移一位,阶码存储变为与0.65相同。

不必担心无法规格化的数,其阶数e规定为1-127=-126,已经为最小阶数,所以必然由其向另一操作数对齐。


c. 尾数相加与检查溢出

当我们对两个操作数完成上述操作,自然可以对其尾数进行相加。如果没有溢出,那么皆大欢喜。可惜世事不可尽如人意v_v
尤其需要强调的一点是:计算机中加减法实际都是采用加法硬件来进行计算,所以当出现负浮点数时,虽然负浮点数存储的二进制尾数依然是原码,但在计算时需要将其转化为补码来实现用加法的硬件完成操作

对于浮点数而言,当两个正操作数相加超过表示范围,称为上溢出;当两个负操作数相加超过表示范围,称为下溢出;(若溢出后的情况与定义的特殊情况相同,则按照特殊情况处理)

通常来说有两种方式判断溢出,分别是 进位判断法双符号判断法

  • 进位判断法(采用单符号位:在计算数值前面补上符号位)
    • 无溢出:符号位 和 最高位 一起进位或一起不发生进位。
    • 溢出:符号位 或 最高位 其中一个发生进位。
  • 双符号判断法(采用双符号位:在计算数值前面补两个符号位)
    • 无溢出:计算后两符号位相同。
    • 上溢出:计算后两符号位为01。
    • 下溢出:计算后两符号位为10。

这里的计算数值是在尾数之前补上对阶之后的隐藏位,以上述为例

在这里插入图片描述

此时进行0.65+(-0.425)操作,必须强调的是,用于计算的负数尾数需要化为补码

~(11011001100110011001101)+1->00100110011001100110011进位判断法(单符号位)0-1-01001100110011001100110 单符号位-隐藏位-尾数 0.65
+ 1-0-00100110011001100110011 单符号位-隐藏位-尾数 -0.425
->0-0-01110011001100110011001 符号位与计算最高位都产生进位 无溢出
所以两操作数计算结果的隐藏位为0,符号数为0,
阶码为01111110(与操作数保持一致)
尾数为01110011001100110011001双符号判断法00-1-01001100110011001100110 单符号位-隐藏位-尾数 0.65
+ 11-0-00100110011001100110011 单符号位-隐藏位-尾数 -0.425
->00-0-01110011001100110011001 两个符号位都相同 无溢出
同上

但是我们并不将结果直接存储为0-01111110-01110011001100110011001,因为此时隐藏位为0未规格化,而且还可能需要舍入操作
对结果进行规格化 结果为0-01111100-11001100110011001100100 约等于0.225


d. 结果规格化与溢出处理

在尾数相加的过程中,尾数最高位可能产生进位,称为尾数上溢
对阶的过程中,尾数最低有效位可能被舍去,为尾数下溢

  • 尾数上溢 两个同符号尾数相加产生了最高位向上的进位,要将尾数右移,阶码增 1
    来重新对齐。
  • 尾数下溢 在将尾数右移时,尾数的最低有效位从尾数域右端流出,要进行舍入处理(在步骤e中说)。

当出现尾数上溢时,需要向右规格化则尾数右移1位,阶码+1,因此浮点数相加时尾数的溢出也被称为可补救的
若无溢出,则按照最基本的规格化方式,即规格化为1.xxx的形式(不考虑非规格化数)——1依然是隐藏位,xxx为存储的尾数二进制,阶码同步变化。(即所谓的左规,实际就是最普通的规格化过程)

在规格化时,阶码往往也会产生变化

  • 阶码上溢 超过了阶码可能表示的最大值的正指数值,一般将其认为是+∞和–∞。
  • 阶码下溢 超过了阶码可能表示的最小值的负指数值,一般将其认为是 0。

e.舍入处理

IEEE754 标准中,对舍入处理提供了四种可选办法。

  • 朝 0 舍入 即朝数轴原点方向舍入,就是简单的截尾。无论尾数是正数还是负数,截
    尾都使取值的绝对值比原值的绝对值小。这种方法容易导致误差累积。
  • 朝+∞舍入 对正数来说,只要多余位不全为 0 则向最低有效位进 1;对负数来说,则
    是简单的截尾。
  • 朝–∞舍入 处理方法正好与朝+∞舍入情况相反。对正数来说,则是简单截尾;对负
    数来说,只要多余位不全为 0,则向最低有效位进 1
  • 向偶数舍入(就近舍入)(default)

这里着重说一下为什么这是默认的方法,以及具体使用方法:
如果我们总是把两个可表示值中间的数字向上舍入,采用这种方式舍入得到的一组数的平均值将比这些数本身的平均值略高一些。相反,那么舍入后的一组数的平均值将比这些数本身的平均值略低一些。这些方法会在计算这些值的平均数中引入统计偏差。向偶数舍入在大多数现实情况中避免了这种统计偏差

因此假设我们想将十进制数舍入到最接近的百分位。不管用那种舍入方式,我们都将把1.2349999舍入到1.23,而将1.2350001舍入到1.24,因为它们不是在1.23和1.24的正中间。另一方面我们将把两个数1.2350000和1.2450000都舍入到1.24,因为4是偶数。
而在二进制中,每一位的权重都是前一位权重的二分之一,因此当一位为1(设其为第n位)时,实际我们知道n位及之后的尾数和一定大于等于第n-1位权重的一半,如下图例。因此我们说——在尾数右移时,被移去的最高数值位为0,则舍去。被移去的最高数值位为1,则在尾数末尾加1(舍0入1法);这样做可能使尾数又溢出,此时需要再做一次右规。,实际就是向偶数舍入。(如果你理解成简单的四舍五入是绝对错误的)

在这里插入图片描述
还有一种恒置1法,不在此赘述。


Some tips: 为什么进位/双符号判断法有效的通俗解释?

  • 首先我们回忆一下补码转化为十进制的快捷方式:最高位取负值 其余位取正值 相加可得十进制。
    如11001->转化为十进制-16+8+1=-7。所以实际上补码越大,实际值越靠近0(实际值的绝对值越小)
    在这里插入图片描述

  • 对于单符号位(进位)判断法:

    • 正数加正数的情况下,由于符号位都是0,所以符号位不可能向前产生进位,所以溢出也就意味着数值最高位向前进位,最终导致结果符号位是1,计算结果出错。此时符号位没有进位,数值最高位进位。
    • 负数加负数的情况,因为两个符号位均为1 ,所以必定会在符号位产生进位。当补码比较大时候,此时若数值最高位产生进位,实际两者之和绝对值很小,同时将符号位重新置1;只有当补码很小,实际值的绝对值很大时,剩下的数值位的最高位相加之后才有可能不向前进位,这时候符号位变成了0,也就是两个负数相加得到了正数,计算结果错误。
    • 正负数相加情况此时也很容易理解了。所以该种方法判断溢出是符号位或最高位其中一个发生进位。
  • 对于双符号判断法:

    • 正数加正数,符号位相加为00,若数值位最高位产生进位,溢出时符号必然为01
    • 负数加负数,符号位相加为10,若数值位最高位产生进位,则说明操作数的的补码很大,实际值很小,必然不会溢出,产生进位后符号位为11。
    • 正数加负数,符号位相加为11,若数值位最高位产生进位,则说明正数很大,负数很小,结果也不会溢出,产生进位后符号位为00;若不产生进位,符号位依然为11。都不溢出

浮点数加减的基本结构示意图
在这里插入图片描述


Some tips:符号位拓展

  • 对于有符号整数,例如如何将32位数据正确的拷贝到64位机器?我们只需要将它的符号位不断拷贝即可。对于正数,符号位为0,左边补0自然不影响大小。
  • 对于负数,符号位为1,假设原符号位权重为2n,向左拷贝一位后新符号位权重为2n+1,但此时转换十进制时原符号位权重已经取正数,实际各位权重之和对数值本身并无影响
    在这里插入图片描述
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/1330.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【归并】Leetcode 排序数组

题目讲解 912. 排序数组 算法讲解 使用归并算法排序数组&#xff0c;我们先在数组中寻找一个mid点&#xff0c;然后把数组分成了两部分&#xff0c;我们先排左部分&#xff0c;排左边部分的时候有需要将当前的子数组分成两部分&#xff0c;继续循环&#xff0c;直到当前子数组…

【结构型模式】装饰器模式

​一、装饰器模式概述 装饰器模式&#xff08;装饰者模式&#xff09;定义&#xff1a;装饰器模式动态地将责任附加到对象上。若要拓展功能&#xff0c;装饰者提供了比继承更有弹性地替代方案。&#xff08;对象结构型模型&#xff09;通俗点来说&#xff1a;动态的给一个对象增…

淘宝购物更智能:taobao.item_search API接口实现关键字精准匹配

随着电子商务的飞速发展&#xff0c;淘宝作为中国最大的网络购物平台之一&#xff0c;为亿万消费者提供了便捷、丰富的购物体验。然而&#xff0c;在海量商品中快速找到符合自己需求的商品&#xff0c;一直是消费者面临的挑战。为了提升购物体验&#xff0c;淘宝开放平台提供了…

【JS】js数字转k、w结尾 | 1000 = 1k

问题 数字转k、w结尾 如&#xff1a;10001k 100001w 码 /*** 数字转k,w* param {Number} num * returns String*/ const numberTokw num > {if (num < 1000) return numlet endStr w,numVal 10000;if (num > 999 && num < 10000) {endStr knumVal …

使用python socket搭建Client测试平台

目录 概述 1 背景 2 Client功能实现 2.1 何谓Client 2.2 代码功能介绍 2.3 代码实现 2.3.1 代码介绍 2.3.2 代码内容 3 测试 3.1 PC上创建Server 3.2 同一台PC上运行Client 3.2.1 建立连接 3.2.2 测试数据交互 3.3 Linux 环境下运行Client 3.3.1 建立连接 3.3.…

ElasticSearch实战之项目搜索高亮

文章目录 1. 前情配置2、数据操作2.1 操作API2.2 数据入库 3. 高亮搜索3.1 方法封装3.2 高亮搜索 1. 前情配置 为满足ElasticSearch可在项目中实现搜索高亮&#xff0c;我们需要先做一些前情配置 导入ElasticSearch依赖 <dependency><groupId>org.springframewor…

EPSON晶振应用到汽车电子产品上的型号有哪些?

EPSON品牌应用在汽车电子产品上的晶振.&#xff0c;当然也少不了晶振可能最熟悉的就是32.768K系列和26MHZGPS晶振用的多。 在汽车里每一个部件都应有的不一样,甚至多次使用到同一尺寸,不同频率的晶振.爱普生品牌晶振型号就有几百种,很容易混淆,要想记住汽车里所应用到的不是件…

B树(B-tree)

B树(B-tree) B树(B-tree)是一种自平衡的多路查找树&#xff0c;主要用于磁盘或其他直接存取的辅助存储设备 B树能够保持数据有序&#xff0c;并允许在对数时间内完成查找、插入及删除等操作 这种数据结构常被应用在数据库和文件系统的实现上 B树的特点包括&#xff1a; B树为…

学习空间转换-3D转换

1.什么是空间转换&#xff1f; 使用的是transform属性实现元素在空间内的位移&#xff0c;旋转&#xff0c;缩放等效果。 空间&#xff1a;是从坐标轴角度定义的。x,y,z三条坐标轴构成的一个立体空间&#xff0c;Z轴位置与视线方向相同。 所以空间转换也被叫做3D转换 语法&a…

PICkit 3 v3.10中的 Device Family 识别不到芯片

1&#xff1a;现象描述 在使用 PICkit3烧写hex文件的时候&#xff0c;Device Family只有默认芯片&#xff0c;识别不到当前使用的芯片&#xff0c;导致报错“Device Error - hex file not loaded”&#xff0c;我当前使用的是 PIC16F1826芯片&#xff0c;默认不支持&#xff1…

快速开发部署平台Replit

Replit 是可以快速搭建开发、部署环境的平台。能够快速将原型进行部署&#xff0c;代码编辑器支持协同开发&#xff0c;他的在线编辑器做的不错&#xff0c;相当于云上提供了一个 vscode&#xff0c;代码实时更新。Replit 底层是基于容器技术的&#xff0c;可以安全的隔离多个用…

html、css、QQ音乐移动端静态页面,资源免费分享,可作为参考,提供InsCode在线运行演示

CSDN将我上传的免费资源私自变成VIP专享资源&#xff0c;且作为作者的我不可修改为免费资源&#xff0c;不可删除&#xff0c;寻找客服无果&#xff0c;很愤怒&#xff0c;&#xff08;我发布免费资源就是希望大家能免费一起用、一起学习&#xff09;&#xff0c;接下来继续寻找…

分享|网红阳哥介绍的项目能赚钱吗?具体有哪些项目?

在当今的互联网时代&#xff0c;网红的影响力不容小觑&#xff0c;他们通过分享自己的经验和见解&#xff0c;往往能带动一股潮流或引领一种趋势。其中&#xff0c;网红阳哥以其独到的眼光和丰富的经验&#xff0c;分享了一系列赚钱项目&#xff0c;引起了广泛关注。那么&#…

C语言 逻辑运算符

本文 我们来说 逻辑运算符 有时做出决策需要测试多个条件&#xff0c;C语言提供了用于将简单条件组合成复杂条件的逻辑运算符。 逻辑运算符 如下图 用逻辑运算符连接操作数组成的表达式称为逻辑表达式。 逻辑运算的结果只有0和1 逻辑运算的对象可以是任意数值型&#xff0c;但…

VMWare Ubuntu压缩虚拟磁盘

VMWare中ubuntu会越用越大&#xff0c;直到占满预分配的空间 即使系统里没有那么多东西 命令清理 开机->open Terminal sudo vmware-toolbox-cmd disk shrink /关机-> 编辑虚拟机设置->硬盘->碎片整理&压缩 磁盘应用 开机->disk usage analyzer(应用) …

Springboot+Vue项目-基于Java+MySQL的影城管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

苹果 IPA 应用部署软件 iMazing 3 Windows 版获 3.0.0.4 Beta 4

在数字化时代&#xff0c;我们的iOS设备已经成为生活中不可或缺的一部分。为了更加高效、便捷地管理这些设备&#xff0c;iMazing 3.0.0.3 应运而生&#xff0c;它以其独特的功能和卓越的性能&#xff0c;为用户带来了前所未有的全新体验。 首先&#xff0c;iMazing 3.0.0.3 提…

2024第二十一届五一数学建模B题思路 五一杯建模思路

文章目录 1 赛题思路2 比赛日期和时间3 组织机构4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间&#xff1a;2024…

机器学习-随机森林算法预测房租模型

文章目录 机器学习-随机森林算法预测房租模型解决问题数据集探索性数据分析数据预处理构建模型并训练结果分析与评估参数调优结果预测模型保存经验总结参考文章 机器学习-随机森林算法预测房租模型 解决问题 根据待租房源相关信息&#xff0c;通过随机森林机器学习算法构件预…

车载以太网DoIP 协议,万字长文详解

&#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&#x1f345; 玩转CANoe&…