PC_规格化数及尾数相关表示形式和范围
文章目录
规格化浮点数以及规格化
- 为了提高浮点数的
精度
,其尾数必须为规格化数。 - 🎈下面讨论的小数均为原码表示
- 如果不是规格化数,就要通过
修改阶码
并同时左右移尾数
的办法,使其变成规格化数。 - 将非规格化数转换成规格化数的过程称为规格化。(等值转换)
- 对于
基数
不同的浮点数,因其规格化数的形式不同
,规格化过程也不同
。
- 对于
不同基数下的浮点数的规格化数判断
-
当基数为2时,
尾数最高位为1
的数为规格化数。- 设被规格化的数为 F r = 2 F_{r=2} Fr=2
- 即,规格化数的尾数的绝对值不小于 1 2 \frac{1}{2} 21
- 规格化时分为左归和右归
-
尾数左移
1位( F 2 F_2 F2总大小相当于被乘以2,那么为了保持大小不变,必须再除以2,- 这可以通过将阶码减1(这种规格化称为向左规格化,简称
左规
); - 根据需要,反复执行上述操作
- 比如对 F 2 = 2 3 ⋅ 0.001 F_2=2^{3}\cdot0.001 F2=23⋅0.001执行2次左归操作,得到 F 2 = 2 1 ⋅ 0.1 F_2=2^{1}\cdot{0.1} F2=21⋅0.1
- 这可以通过将阶码减1(这种规格化称为向左规格化,简称
-
尾数右移
1位,阶码加1(这种规格化称为向右规格化,简称右规
)。- 和左归是相反的操作
- 比如对 F 2 = 2 3 ⋅ 111.01 F_2=2^{3}\cdot111.01 F2=23⋅111.01执行2次右归操作,得到 F 2 = 2 5 ⋅ 0.1101 F_2=2^{5}\cdot{0.1101} F2=25⋅0.1101
-
-
当基数为4= 2 2 2^2 22时,尾数的
最高两位不全为零
的数为规格化数。-
设被规格化的数为 F = F r = 4 = 4 j ⋅ S f S 1 S 2 ⋯ S n F=F_{r=4}=4^j\cdot{S_fS_1S_2\cdots{S_n}} F=Fr=4=4j⋅SfS1S2⋯Sn
-
规格化时,尾数左移2位,阶码减1 ;
-
尾数右移2位,阶码加1。
-
通俗的讲,就是规格化要考虑到基数,其指数(阶码的+1/-1)就会导致整个数F的大小乘以或者除以4
- 4 = 2 2 4=2^2 4=22从而造成尾数S的连续2次的移位
-
因此,如果最高位两位 S 1 S 2 = 01 S_1S_2=01 S1S2=01,那么是无法仅仅将二进制串左移一位来消掉尾数 S 1 = 0 S_1=0 S1=0的,因为阶码变化1,整个值会变化4倍(或者说除以4);导致操作前后的值不想等,因此,只能够认为, S 1 S 2 = 01 S_1S_2=01 S1S2=01也是属于基数r=4下的规格化数
-
-
当基数为8= 2 3 2^3 23时,尾数的最高三位不全为零的数为规格化数。
- 规格化时,尾数左移三位,阶码减1;
- 尾数右移三位,阶码加1。
🎈小结:规格化数和规格化的推广
-
当
基
数
为
r
=
2
k
时
,
当基数为r=2^k时,
当基数为r=2k时,尾数的最高k位不全为0的浮点数是规格化数
- 左归规格化时,尾数每左移k位,阶码减去1
- 有规格化时,尾数每右移k位,阶码加上1
- 浮点机中一旦基数确定后就不再变了
- 而且基数是隐含的,故不同基数的浮点数表示形式完全相同。
- 但基数不同,对数的表示范围和精度等都有影响。
- 一般来说,基数r越大
- 可表示的浮点数范围越大
- 可表示的数的个数越多。
- 但是浮点数的精度反而下降。
- 如r = 16的浮点数,因其规格化数的尾数最高三位可能出现零,故与其尾数位数相同的r =2的浮点数相比,后者可能比前者多三位精度。
🎈规格化浮点数的表示范围
- 规格化数的表示范围和非规格化数的表示范围由所不同
- 主要变化就体现在尾数S上
- 根据上面的分析,规格化数的尾数S的绝对值有范围约束:
- 就是规格化数F的绝对值
∣
S
∣
∈
[
1
R
,
1
]
|S|\in{[\frac{1}{R},1]}
∣S∣∈[R1,1],设
R
=
2
k
R=2^k
R=2k
- 比 如 , r = 2 , 规 格 化 后 的 ∣ S ∣ ∈ [ 1 2 , 1 ] 比如,r=2,规格化后的|S|\in[\frac{1}{2},1] 比如,r=2,规格化后的∣S∣∈[21,1]
- 对于负规格化浮点数(S<0):
-
S
∈
[
R
−
1
−
1
,
R
−
1
]
S\in[R^{-1}-1,R^{-1}]
S∈[R−1−1,R−1]
- 例 如 R = 4 , S ∈ [ − 3 4 , − 1 4 ] = [ 1.1 1 2 , 1.0 1 2 ] 例如R=4,S\in[-\frac{3}{4},-\frac{1}{4}]=[1.11_2,1.01_2] 例如R=4,S∈[−43,−41]=[1.112,1.012]
-
S
∈
[
R
−
1
−
1
,
R
−
1
]
S\in[R^{-1}-1,R^{-1}]
S∈[R−1−1,R−1]
- 对于正规格话数(S>0):
- S ∈ [ 1 4 , 3 4 ] = [ 0.0 1 2 , 1.1 1 2 ] S\in[\frac{1}{4},\frac{3}{4}]=[0.01_2,1.11_2] S∈[41,43]=[0.012,1.112]
- 就是规格化数F的绝对值
∣
S
∣
∈
[
1
R
,
1
]
|S|\in{[\frac{1}{R},1]}
∣S∣∈[R1,1],设
R
=
2
k
R=2^k
R=2k
规格化数的补码形式
-
仅讨论基数为 r = 2 1 r=2^1 r=21的情况:
-
规 格 化 数 x = x 0 . x 1 ⋯ x n 的 绝 对 值 ∣ x ∣ ∈ [ 1 2 , 1 ) 规格化数x=x_0.x_1\cdots{x_n}的绝对值|x|\in[\frac{1}{2},1) 规格化数x=x0.x1⋯xn的绝对值∣x∣∈[21,1)
-
更具体的应该是:
-
x ∈ ( − 1 , − 1 2 ] ∪ [ 1 2 , 1 ) x\in(-1,-\frac{1}{2}]\cup[\frac{1}{2},1) x∈(−1,−21]∪[21,1)
-
而经过特别规定,对应的真值范围成了:
-
x ∈ [ − 1 , − 1 2 ) ∪ [ 1 2 , 1 ) x\in[-1,-\frac{1}{2})\cup[\frac{1}{2},1) x∈[−1,−21)∪[21,1)
-
-
可以去到-1是补码定点小数补码能够表示-1这一点为基础
-
这里不讨论原码表示
-
-
x > 0 时 , x = + 0.1 ⋯ x>0时,x=+0.1\cdots x>0时,x=+0.1⋯
- x ∈ [ 1 2 , 1 ) x\in[\frac{1}{2},1) x∈[21,1)
-
C
(
x
)
=
T
(
x
)
=
0.
x
1
x
2
⋯
=
0.1
⋯
C(x)=T(x)=0.x_1x_2\cdots=0.1\cdots
C(x)=T(x)=0.x1x2⋯=0.1⋯
- 其中 x 1 = 1 x_1=1 x1=1
- 双 符 号 位 : C ( x ) = 00.1 ⋯ 双符号位:C(x)=00.1\cdots 双符号位:C(x)=00.1⋯
-
x < 0 时 x<0时 x<0时
- 根据区间的对称性: x = − 0.1 ⋯ x=-0.1\cdots x=−0.1⋯
-
设
C
(
−
x
)
=
C
(
−
0.1
⋯
)
=
b
0
.
b
1
b
2
⋯
=
1.
?
设C(-x)=C(-0.1\cdots)=b_0.b_1b_2\cdots=1.?
设C(−x)=C(−0.1⋯)=b0.b1b2⋯=1.?
-
b
0
b_0
b0:
- 由于 − x < 0 -x<0 −x<0,我们可以确定 b 0 = 1 b_0=1 b0=1
-
b
1
:
b_1:
b1:
- cases1:
b
1
=
0
b_1=0
b1=0
- 如 果 x 2 ⋯ x n 中 部 分 二 进 制 串 中 有 1 , 那 么 C ( − x ) = b 1 = x 1 ‾ = 0 如果x_2\cdots{x_n}中部分二进制串中有1,那么C(-x)=b_1=\overline{x_1}=0 如果x2⋯xn中部分二进制串中有1,那么C(−x)=b1=x1=0
- cases2:
b
1
=
1
b_1=1
b1=1
-
否
则
,
x
1
=
1
否则,x_1=1
否则,x1=1就是小数数值部分的从低位到高位出现的第一个1(其余位都为0)
- 它使得 b 1 ⋯ b n = x 1 ⋯ x m b_1\cdots{b_n}=x_1\cdots{x_m} b1⋯bn=x1⋯xm
- 即有 b 1 = x 1 = 1 b_1=x_1=1 b1=x1=1
- 为什么是这样,查看推导
- 这种情况下,尾数真值
x
=
−
1
2
x=-\frac{1}{2}
x=−21
- C ( x ) = 1.10 ⋯ 00 C(x)=1.10\cdots{00} C(x)=1.10⋯00
- 🎈为了便于硬件判断,特别规定这种情况(x= − 1 2 -\frac{1}{2} −21)不是规格化数!
- 🎈尾数真值为-1时,认定为是规格化数
- 既然不是规格化数,就需要规格化
- 在讨论算数移位的时候,我们知道,补码的符号位和第一位有效位相等时,配合阶码-1(基数r=2时),执行移位操作不会发生错误,而且保持等值
-
这
就
得
到
了
C
(
x
)
=
1.10
⋯
0
移
位
后
的
结
果
C
(
x
)
=
1.0
⋯
0
这就得到了C(x)=1.10\cdots0移位后的结果C(x)=1.0\cdots{0}
这就得到了C(x)=1.10⋯0移位后的结果C(x)=1.0⋯0
- 这个真值恰好是-1
- 定点小数恰好能够表示-1
- 用 双 符 号 位 表 示 C ( x ) = 11.0 ⋯ 0 用双符号位表示C(x)=11.0\cdots{0} 用双符号位表示C(x)=11.0⋯0
-
否
则
,
x
1
=
1
否则,x_1=1
否则,x1=1就是小数数值部分的从低位到高位出现的第一个1(其余位都为0)
- cases1:
b
1
=
0
b_1=0
b1=0
- 因此,综上,当x的补码形式C(x)的符号位和第一位数值位不同时,(即 x 0 ≠ x 1 x_0\neq x_1 x0=x1时),该浮点数是规格化的
-
b
0
b_0
b0:
- 双 符 号 位 : C ( x ) = 11.0 ⋯ 双符号位:C(x)=11.0\cdots 双符号位:C(x)=11.0⋯
-
总综合上述结论:当以补码形式表示的位数S的符号位和第一位数值位相异(不同)时,就是规格化数
-
-
补码规格化数下的最值形式
- 补码规格化尾数的
- 最小负数形式(对应真值为-1),补码形式为: 1.00 ⋯ 0 1.00\cdots{0} 1.00⋯0
- 最大负数形式为
1.01
⋯
1
1.01 \cdots 1
1.01⋯1 ,
- 而不是原码的形式 1.10 ⋯ 0 原 1.10 \cdots 0_{原} 1.10⋯0原(对应真值为 − 1 2 -\frac{1}{2} −21) ,
- 1.10 ⋯ 0 1.10 \cdots 0 1.10⋯0 不是补码规格化数,所以规格化尾数的最大负数是 − ( 0.10 ⋯ 0 + 0.0 ⋯ 01 ) 真 = − 0.10 ⋯ 0 1 真 -(0.10 \cdots 0+0.0 \cdots 01)_{真}=-0.10 \cdots 01_{真} −(0.10⋯0+0.0⋯01)真=−0.10⋯01真 ,
- 而 ( − 0.10 ⋯ 01 ) 补 = 1.01 ⋯ 1 (-0.10 \cdots 01)_{补}=1.01 \cdots 1 (−0.10⋯01)补=1.01⋯1
补码下的规格化操作
- 更加前面的讨论和总结,我们可以轻松的判断补码下的规格化数应该是什么样的
- 但是为进行规格化操作,必须会判断定的数(补码)是哪一种情况:
- 绝对值太小:需要进行左归(尾数倍增基数,阶码减小)
- 绝对值太大,(伪)溢出:需要进行右归(尾数)
左规
-
当尾数的第一位数值位和符号位相同(如果是双符号位,双符号位同时相同)
- 即:尾数出现:
- 00.0 ⋯ 00.0\cdots 00.0⋯
- 11.1 ⋯ 11.1\cdots 11.1⋯
- 如何推导这个结论?
- 我们依然从绝对值大小(范围)的角度入手
- 由对称性,可以得到对应于尾数为负数的形式
- 当
S
∈
(
0
,
1
2
)
S\in(0,\frac{1}{2})
S∈(0,21)属于需要左归的情况
- S = + 0.0 ⋯ S=+0.0\cdots S=+0.0⋯
- 补 码 : C ( S ) = 0.0 ⋯ 补码:C(S)=0.0\cdots 补码:C(S)=0.0⋯
- 双符号位: 00.0 ⋯ 00.0\cdots 00.0⋯
-
−
S
∈
(
−
1
2
,
0
)
-S\in(-\frac{1}{2},0)
−S∈(−21,0)
- C ( − S ) = 1.1 ⋅ ⋯ C(-S)=1.1\cdot{\cdots} C(−S)=1.1⋅⋯
- 双符号位: 11.1 ⋯ 11.1\cdots 11.1⋯
- 我们依然从绝对值大小(范围)的角度入手
- 是尾数绝对值太小的表现,应该执行左归
- 左归时,将尾数左移,阶码减一
- 即:尾数出现:
例子
- 某 个 尾 数 求 和 结 果 为 : ( x + y ) 补 = 00 , 11 ; 11.1001 分 号 前 面 是 双 符 号 位 的 阶 码 ( 补 码 形 式 ) , 分 号 后 面 是 尾 数 补 码 容 易 发 现 , 双 符 号 位 的 连 个 b i t 是 不 同 的 ( 发 生 了 溢 出 ) 最 高 位 为 0 , 发 生 的 是 正 溢 出 ( 结 果 超 过 1 了 ) 现 在 需 要 进 行 右 归 ( 右 移 1 位 ) 得 到 ( x + y ) 补 ′ = 00 , 10 ; 11.0010 即 : x + y = − 0.111 0 2 ⋅ 2 2 某个尾数求和结果为: \\(x+y)_补=00,11;11.1001 \\分号前面是双符号位的阶码(补码形式),分号后面是尾数补码 \\容易发现,双符号位的连个bit是不同的(发生了溢出) \\最高位为0,发生的是正溢出(结果超过1了) \\现在需要进行右归(右移1位) \\\\ 得到(x+y)'_补=00,10;11.0010 \\即:x+y={-0.1110_2}\cdot{2^2} 某个尾数求和结果为:(x+y)补=00,11;11.1001分号前面是双符号位的阶码(补码形式),分号后面是尾数补码容易发现,双符号位的连个bit是不同的(发生了溢出)最高位为0,发生的是正溢出(结果超过1了)现在需要进行右归(右移1位)得到(x+y)补′=00,10;11.0010即:x+y=−0.11102⋅22
右规
- 如果非规格化尾数出现上述两类情况之外的情况:
- 01. ⋯ 01.\cdots 01.⋯
- 10. ⋯ 10.\cdots 10.⋯
- 那么是尾数绝对值太大导致的定点溢出,需要进行右移
伪溢出
- 当尾数出现01.x x…×或10.x x…x时,表示尾数(顶点数)溢出,这在
定点加减运算
中是不允许的, - 但在
浮点运算
中这不算溢出,可通过右规处理
。- 右规时尾数右移一位,阶码加1
例
- 某 个 尾 数 求 和 结 果 为 : ( x + y ) 补 = 00 , 10 ; 01.0010 分 号 前 面 是 双 符 号 位 的 阶 码 ( 补 码 形 式 ) , 分 号 后 面 是 尾 数 补 码 容 易 发 现 , 双 符 号 位 的 连 个 b i t 是 不 同 的 ( 发 生 了 溢 出 ) 最 高 位 为 0 , 发 生 的 是 正 溢 出 ( 结 果 超 过 1 了 ) 现 在 需 要 进 行 右 归 ( 右 移 1 位 ) 得 到 ( x + y ) 补 ′ = 00 , 11 ; 00.1001 即 : x + y = 0.110 1 2 ⋅ 2 3 某个尾数求和结果为: \\(x+y)_补=00,10;01.0010 \\分号前面是双符号位的阶码(补码形式),分号后面是尾数补码 \\容易发现,双符号位的连个bit是不同的(发生了溢出) \\最高位为0,发生的是正溢出(结果超过1了) \\现在需要进行右归(右移1位) \\\\ 得到(x+y)'_补=00,11;00.1001 \\即:x+y={0.1101_2}\cdot{2^3} 某个尾数求和结果为:(x+y)补=00,10;01.0010分号前面是双符号位的阶码(补码形式),分号后面是尾数补码容易发现,双符号位的连个bit是不同的(发生了溢出)最高位为0,发生的是正溢出(结果超过1了)现在需要进行右归(右移1位)得到(x+y)补′=00,11;00.1001即:x+y=0.11012⋅23
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」