📢博客主页:https://blog.csdn.net/2301_779549673
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 JohnKi 原创,首发于 CSDN🙉
📢未来很长,值得我们全力奔赴更美好的生活✨
文章目录
- 📢前言
- 🏳️🌈1. 浮点数的规格化表示
- ❤️ 1.1 为什么要规格化
- 🧡 1.2 规格化的特点
- 💛 1.3 浮点数的表示范围
- 🏳️🌈2. IEEE 754
- ❤️ 2.1 偏置值和移码的概念
- 🧡 2.2 IEEE 754标准
- 💛 2.3 IEEE 754浮点数的范围
- 👥总结
📢前言
浮点数在计算机中起着至关重要的作用。在位数固定的情况下,定点数能表示的数字范围有限,而浮点数则可以在相同的位数下扩大数的表示范围,同时尽可能地保持有效精度。
而计算机中的浮点数不论是从储存还是运算都与我们生活中的计算方式大相径庭,所以初学者在刚刚学习时总是很难理清规格化、IEEE及运算原理,这里笔者就从自己的理解出发,根据哔站王道考研课程及其教材进行一下难点总结
总思路图如下
🏳️🌈1. 浮点数的规格化表示
规格化浮点数的目的主要是为了在计算机中更有效地表示和处理数值,提高数值的精度和运算的准确性。同时,规格化的表示方法可以使计算机在进行浮点数运算时遵循统一的规则,便于硬件设计和实现。
❤️ 1.1 为什么要规格化
先看个例子
- 逗号前为符号位,分号分隔阶码和尾数
所以a的阶码为 +1(十进制,即2的+1次方)
, 尾数为 -0.1001(二进制)
,
真值就为 -0.1001 * 2^1
即 -1.001(二进制)
8位时表示为 0 01 1 1001
b也是相同道理,阶码为 +2(十进制,即2的+1次方)
, 尾数为 0.01001(二进制)
,
真值就为 0.01001 * 2^1
即 1.001(二进制)
8位时表示为 0 10 0 0100
,最后一个1因为超出被舍弃了
很显然这种情况很容易在存储空间不够时造成了精度的丢失,为了有效地提高精度,就需要对浮点数进行规格化,也就是使有效数字尽量沾满尾数数位
。
规格化的基本操作就是使非零浮点数在尾数的最高数位上保证是一个有效值
所以需要对b进行规格化处理,即对尾数部分左移一位,与此同时阶码部分因为尾数左移了一位就要减1,所以最后规格化下,b的8位表示为 0 10 0 1001
,这个做法也成为左规 - 左移n位
相应的,存在右规,就是因为尾数影响到了符号位,需要对尾数部分右移。提一嘴,往往通过双符号位的方法判断是否影响
左规:当浮点数运算的结果为非规格化时要进行规格化处理,将尾数算数左移一位,阶码减1。
右规:当浮点数运算的结果尾数出现溢出(双符号位为01或10)时,将尾数算数右移一位,阶码加1。
举个例子:
这里就用到了双符号位通过判断符号位的与关系,判断运算是否导致了溢出(这里因为原本是负数,相加后溢出,所以是负溢出,更高的符号位为正确的符号),然后利用右规使其规格化
🧡 1.2 规格化的特点
这里别的没啥好说的主要的负数的补码部分
因为是复数的补码,所以假设一个负数原来是1.10001
,那么它的补码的就是1.01111
。所以它往往是以1.0xxx
的形式出现的
为了记快一点,可以理解为补码的符号位和位数最高位必须不同,即为0.1
或1.0
开头
还有负数补码的最小值,我是这么理解的
- 二进制负数的最小值为全1
- 原码转补码是,去符号位,取反,加1
- 所以补码去开头
1.0
后面全0,即1.00...0
- 此时对应的就是-1,按理说这是浮点数到不了的值,但是因为是补码存在取反加一的可能就出现了这个值。
tip1:在规格化时,题目会说此时是补码还是原码,不需要进行转换,直接右规、左规实现规格化就行了
tip2:补码规格化时,右移高位补1,左移低位补0,
举个例子:
- 负数补码规格化,
1.0
开头,直接左规或右规 - 负数补码低位补0,高位补1,所以右移是不行的
- 负数补码小数点后面紧跟的1可以都看成原码的0,不影响最终值
- 左移3位,达到
1.0100000
- 尾数左移3位,阶数减3,阶数为
0.011
- 结果为
0.011;1.0100000
💛 1.3 浮点数的表示范围
运算结果大于最大正数时称为正上溢,小于绝对值最大负数时称为负上溢,正上溢和负上溢统称上溢
。
数据一旦产生上溢,计算机必须中断运算操作,进行溢出处理。
当运算结果在0至最小正数之间时称为正下溢,在0至绝对值最小负数之间时称为负下溢,正下溢和负下溢统称下溢
数据下溢时,浮点数值趋于零,计算机将其当作机器零处理。
这种产生上下溢的行为,往往是在运算中导致的
🏳️🌈2. IEEE 754
❤️ 2.1 偏置值和移码的概念
在无特定说明的情况下不论是一般的前面讲的规格化的浮点数还是IEEE 754的他们的阶码都是移码,有特别说明的话就是题干中所说,比如1.2中就是补码
偏置值:一般情况下为 64(32位)、128(64位),IEEE 754中为 64-1(32位)、128-1(64位)
移码:真值 + 偏置值
举个例子:IEEE 754标准,32位
令偏置值 = 127D = 0111 1111B,即2^n-1-1
真值 -128 = -1000 0000B
移码 = 偏置值 + 真值 = -1000 0000 + 01111111 = 1111 1111
🧡 2.2 IEEE 754标准
IEEE 754标准
比一般的 规格化浮点数
更标准,规格化浮点数往往会因为题干的不同而发生明显变化,这体现在表示格式、偏置值、阶码尾数的表现形式等方面,比如说
- 1位阶码符号 + 3位阶码 + 1位尾数符号 + 7位尾数
- 1位符号 + 7位阶码 + 24位尾数
可IEEE 754标准的浮点数,就是符号s +阶码e + 尾数f,毫无例外,并且
- 阶码一定是补码
- 尾数一定是原码
- 偏置值是2的n-1次
一般的偏置值是2的n次,n为阶码的尾数
另外,关于IEEE 754的尾数部分,我们常认为是二进制原码,并且隐藏表示最高位的1,所以尾数部分的实际值为1.M,表示时为M。
举个例子,将十进制数 -8.25 转换为 IEEE 754 单精度浮点数(32位)格式便是
- -8.25 转换为二进制数为 -1000.01 = -1.00001 x 2^3
- 得出阶码 E = 3(真值) +127(偏置值) = 130(移码)
- 所以最后的即 1(1位符号位) + 1000 0010(8位阶码) + 0000 1000 0000 0000 0000 000(23位尾数)
💛 2.3 IEEE 754浮点数的范围
我们先不考虑阶码的全1或全0,那么阶码的取值范围就是[-126,127]
在这种情况下,尾数取任意值都无所谓,
可以全0,表示1.00……0,即1
也可以是全1,表示1.11……1,即1+1/2+1/4+……+1/223 即 2-1/223(32位下)
由此,我们就能得出IEEE 754浮点数的范围
至于阶码全0和全1的情况
- 全0阶码全0尾数: +0/-0。零的符号取决于符号s,一般情况下+0和-0是等效的。
- 全1阶码全0尾数: +∞/-∞。fx在数值上大于所有有限数,-则小于所有有限数。引入无穷大数的目的是,在计算过程出现异常的情况下使得程序能继续进行下去。
- 全1阶码非0尾数: NaN(NotaNumber)。表示一个没有定义的数,称为非数。
- 全0阶码非0尾数: 非规格化数。非规格化数的特点是阶码为全0,尾数高位有一个或几个连续的0,但不全为0。因此,非规格化数的隐藏位为0,且单精度和双精度浮点数的指数分别为-126或-1022。非规格化数可以用于处理阶码下溢。
👥总结
本篇博文对 浮点数的表示及IEEE 754规格化 做了一个较为详细的介绍,不知道对你有没有帮助呢
觉得博主写得还不错的三连支持下吧!会继续努力的~