Uploaded by xincheng lei

CSAPP chapter 2

advertisement
信息的表示和处理
1.information storage
是表示信息的最小单位,但是访问内存时不会去单独的访问某个位(或许是因为那样效率太低下
了)。我们同时至少需要访问8bit 也就是一个字节 Byte ,所以我们称它为 最小的可寻址内存单位
bit
机器级程序
大概是汇编语言编写的较低级别的程序。
机器级程序将内存和其它存储设备(磁盘等) 认知 为一个连续的字节数组(virtual memory),
数组中的每个地址空间被赋予唯一的编号称为它的地址。
1.word size
指出指针数据的标称单位(理解为单位指针可以访问多长的地址范围),书上说的是虚拟地址
按照字来编码即根据 字长 编址。对于一台字长为 ω 的计算机 其虚拟地址的范围为
0
~2
ω−1
意味着一个程序在运行时最大可以访问2ω−1个单位的地址
然而我貌似记得计算机组成中也是这样的,但是是有3种编址方式。
2.vector describe limited collections
存在位向量 BV
[aω−1 , ..., aω−2 , a1 , a0 ]
​
​
​
​
我们可以使用这样的位向量去表示集合
设存在集合
A = {a, b, c, d}
那么我们可以使用
BV
BV ≐ [...ad ...ac ...ab ..., aa ...]
​
‘...’
≐
表示略过的‘0’,标出的
a∗
​
表示
​
​
​
1
的含义是 左边的部分被定义为等于右边的部分
如 Aep1={1,4,3,6} 那么 BV_Aep1={1011010},观察BV_Aep1 的下标 其实是 Aep中元素的值。
对这种位向量施加的逻辑位运算可以等价于在原集合上应用逻辑运算(数学概念中)。
有Aep2={2,3,6,7} 那么 BV_Aep1={11001100}
0
1
0
1
1
0
1
1
1
0
0
1
1
0
BV_Aep1&BV_Aep2
index
7
6
5
4
3
2
1
BV_Aep1
0
1
0
1
1
0
1
BV_Aep2
1
1
0
0
1
1
0
result
0
1
0
0
1
0
0
transfer
{6,3}
to
3. shift operation
一种可以移动 位模式 的运算规则,存在一个位模式
X
[xω−1 , ..., xω−2 , x1 , x0 ]
​
​
​
​
那么 X<<k 会产生一个新的位模式
[xω−k−1 , ..., xω−k−2 , x1 , x0 , 0, ...., 0]
​
​
​
​
将所有位依次向右移动 k位,并且在 位模式的 低位(或和移动方向的相对方向)添加 k 个 0 ,我
们会丢失 所移动方向的 k 个 bit
同样 存在X>>k 但是对于 无符号数 和 有符号数 (补码) 计算机采用在两种不同的策略,对于
unsigned
和右移一致,在最高位添加K个0,然而对于有符号数 最高位代表其本身的符号,所以在移动时复
制原来的符号位代替即 X>>k(有符号)结果如下
[xω−1 , xω−1 , xω−1 , ..., xω−2 , xk ]
​
​
​
​
​
那么我们称这种复制最高位的移位方法为 算术右移 另一种为 逻辑右移
我们总是假设 有符号数在机器中右移时采用算术右移而对于无符号数 必须 逻辑右移
4.unsigned encoded
假设一个整数类型有 ω位,我们可以使用
[xω−1 , xω−2 , xω−3 , ..., x1 , x0 ]
​
​
​
​
​
来表示向量中的每一位 或者使用 x 来表示x 整体 ,在表示位时每个 x∗ 的值为 0 或者 1,我们可以
使用一个函数 B2U (Binary To Unsigned)来表示 以 二进制 表示的 无符号数
​
1) formula 2.1 B2U
w−1
B2Uω (x) ≐ ∑ xi 2i
​
​
i=0
该公式的含义为 ω 位的位模式 被定义为 位模式中的 每一位 乘 2的相应次方 (相应位在位模式中的
下标)的累加和。
那么例如
B2U4 ([1, 0, 1, 1]) = 1 ⋅ 20 + 1 ⋅ 21 + 0 ⋅ 22 + 1 ⋅ 23 = 11
​
)
2 code features
那么 ω 位的位模式一共可以表示 2ω 位数字 所可以表示的范围就是
0
~2
ω
−1
取 Umax 时 位模式中的每一位的值都是 1,反之全为0 取的Umin
从位模式向无符号数的映射是双向的即我们可以通过函数 B2Uw (x) 将一个位模式映射到一个唯
一的 无符号数,那么根据它的唯一性,我们同样可以使用 B2U的反函数记为 U 2B 的函数 将一
个 无符号数映射为一个唯一的长度为 ω 的 位模式
所以我们得到一个特性即
​
​
​
w
​
无符号数编码的唯一性
5.two's-complement emcoded
二进制补码编码
在计算机中补码被用来表示 携带符号的数 位模式的最高位被用来表示符号,例如
下
[xω−1 , xω−2 , xω−3 , ..., x1 , x0 ]
​
​
​
​
​
bit-pattern
如
那么它的最高位 xw−1 将表示负权值 −2ω−1
但是按照之前所学习的只是我可以将补码进行 取反 然后+1的操作,而忽略其最高位权值的含
义,仅仅将其当作符号来看待。
​
当最高位被看作负权我们的转换函数如下
)
1 formula 2.3 B2T
Binary To Two's Complement
w−2
B2Tω (x) ≐ −xω−1 2
​
​
ω−1
+ ∑ xi 2 i
​
​
i=0
很明显如果 位模式中的 xω−1 为1 那么 B2Tω 一定是一个负数。所以可以使用最高位来表示数字
的符号。
那么为负数时它所表示的 有符号数 就是 -2ω−1+{位模式中其它唯一的数和其所代表的权重的乘积的
和
为正数时和无符号数的含义一致但是数据可以表示的范围缩小了。
无符号数时可以表示2ω 数量个正数 但是现在只能表示 2ω−1位
​
​
)
2 code features
由前文的定义我们可以得到 补码的数据范围,当最高位为1时其余为为0时 取的能够表示的最小值
即
Tmin = −2ω−1
​
那么当符号位0 其余位为1时取的最大值
Tmax = 2ω−1 − 1
​
在二进制中有一个快捷的规律(自己发现的)其实也挺简单的
j−1
∑ 2i = 2j − 1
​
i=0
即如果现在是低 i 位,那么 前面 0~ i-1 所有位的和 加上 1等于 低i位的值。在二进制的权重序列
中。
同样根据有符号数和无符号数它们位模式之间的关系我们也易得
Umax = Tmax << 1 + 1
​
​
往左移动移位在最低为补1
在补码的表示中,因为0是非负数占用了一个正数的表示范围(而零既不是正数也不是负数),所
以补码的范围是不对称的也就是说Tmin 没有对应的正数。
这种不对称性会引发一些意想不到的错误 例如如对 Tmin 求绝对值 应该会出错
​
​
6.other representations of signed
signed
还有其它两种表现形式,确实是我以前学过的那种,按照以前对反码的认知,有以下规则
T ow′ s Complement = reserve(Sign − M agnitude) + 1
表示求反 对原码的除符号位的每一位。
那么同时有
reserve
Ones′ Complememt = reverse(Sign − M agnitude)
)
1 One's Complememnt
最高位的权重为 −(2ω−1 − 1) 剩余位的权重和
two's complememt
保持一致,那么B2Oω 如下
​
ω−2
B2Oω (x) = −(2
​
ω−1
− 1)xω−1 ∑ xi 2i
​
​
​
i=0
其实 我们不难发现 −(2ω−1 − 1) 就是 omega − 1 (下标)后面的所有 位 为1 对他们所有取负
号,然后和他们本身所 抵消
index
3
2
1
0
bit'pattren
1
0
1
0
−(2ω−1 )
1
1
1
1
-7
1
0
1
0
2
1
1
0
1
-5
~2
(0
ω−2
)
result
va
)
2 Sign-Magnitude
最高位是符号位,不代表权值,仅仅用来区分正负。
ω−2
B2Sω (x) =)(−1)
​
xω−1
​
∑ xi 2 i
​
​
i=0
7.conversion between signed and unsigned
大多数的C语言实现
和 unsigned 可以互相转换,这种转换是基于位级而不是基于其所表示的数字本身(转换并
不会改变位模式只是改变了解释这个位模式的上下文)
signed
)
1 formula 2.6 B2U
首先是对需要转换的 signed Xt 范围的约束
​
TM in ≤ Xt ≤ TM ax
​
书上的思想大概是这样,求得 T 和 U 的 差 D ,然好 用 T+ D =U; 也就是先求得
D = B2Uω − B2Tω
​
​
w−1
= ∑ xi 2 − (−xω−1 2
i
​
​
w−2
ω−1
​
​
i=0
​
= xω−1 2
ω−1
​
− (−xω−1 2
+ ∑ xi 2 i )
i=0
ω−1
​
)
= xω−1 (2ω−1 + 2ω−1 )
= xω−1 2ω−1 (1 + 1)
​
​
= xω−1 2ω
​
有 B2Tω = x 那么 T 2Uω 就如下
​
​
T 2Uω = xω−1 2ω + x
​
​
举个 栗子 有
X = [1, 0, 1, 0]
那么有
Xt = −8 + 2 = −6
​
那么有
​
​
​
(1)
T 2U = X4−1 24 + Xt
= 16 − 6
= 10
​
​
​
​
(2)
​
就等于 以 unsigned 去解释最初的 位模式
那么可以总结得到
T 2U ω = {
​
x
x + 2ω
x≥0
x<0
​
​
(3)
​
时 最高位的如果存在(不为0)那么它在 unsigned解释方法中是参与计算
的 且它的权重 恰好和 signed 解释方法中的权重相反 那么 它们就差了
distance(−2ω−1 , 2ω−1 ) = 2ω ,所以从 signed 转到 unsigned 是需要移动这么多距离(加上值
一样) 最高位不为0的前提
signed 2 unsigned
)
2 formula 2.8 U2T
有 u是一个 无符号数那么它的范围是 U M in ≤ u ≤ U M ax
书上第一句 设 xu = U 2Bω (u) 不知道有什么用 ,我想是 用 B2Uω 的反函数求得 最初的位模式
然好使用 B2Tω 得到 T
其实实际还是用 T 和 U 的差 D ,使用 U - D 得到 T 那么就有
​
​
​
ut = u − uω−1 2ω
​
那么 ut 就意为 u 2 t 的结果
归纳一下就会有
​
​
U 2Tω = {
​
x
x − 2ω
x ≤ TM ax
x > TM ax
​
​
(4)
​
8.bit extend and truncate
不同字长的整数转换间需要进行位的扩展或者切断,当把一个长字节的数据类型向一个短字节数据类
型转换时我们需要截断多余的位,那么反过来我们要考虑增加的位置应该被设置为什么值 。二者的
前提都是尽量保持操作后的 值 不改变或者尽可能小幅度的改变
)
1 zero extension
将宽度为 ω 的 unsigned 位向量 u = [uω−1 , uω−2 , uω−3 , u0 , u1 ] 扩展 到宽度为 ω′ 的位向量 u'
那么 u'如下
​
​
​
​
​
u′ = [0, ..., 0, uω−1 , uω−2 , uω−3 , u0 , u1 ]
​
u=u'
​
值是没有变的,在最高位 添加了 ω′ − ω 位
​
​
0
)
2 sign extension
符号扩展
用在补码的扩展中,和zero extension 类似,不过在高位使用 n(大宽度和小宽度的差) 位 原本
的符号位的值 xω−1 进行扩展,如果 xω−1 为0 那么和 zero extension 一致 。如果不为 xω−1 0
的证明如下
​
​
​
有宽度为ω的 signed s = [sω−1 , sω−2 , sω−3 , s0 , s1 ] 假设需要扩展 k 位 那么根据我们的法则
是
​
​
​
​
​
s′ = [sω−1 , sω−1 , ...k − 2 ∗ sω−1 , ..., sω−2 , s0 , s1 ]
​
​
​
​
​
​
如果我们能够证明符号位拓展一位能够保持 s的值不变 那么我们就可以依据依次增加一位的理念去
证明 拓展 k位 后的真值不变性 那么
ω−1
B2Tω+1 (s + 1 ) = −sw−1 2 + ∑ si 2i
w
​
​
​
​
​
i=0
ω−2
w
= −sw−1 2 + −sw−1 2
​
w−1
​
+ ∑ s i 2i
​
​
i=0
ω−2
​
= −sw−1 (2ω − 2ω−1 ) + ∑ si 2i
​
​
​
​
​
i=0
ω−2
= −sω−1 2ω−1 + ∑ si 2i
​
​
​
i=0
= B2Tω (s)
​
s+1
​
为 s 扩展一位符号位后的向量 s 为原向量
)
4 unsigned truncate
将一个 ω 位的无符号 u 向量 u = [uω−1 , uω−2 , uω−3 , ..., u1 , u0 ] 截断到 ω′ 位,得到 u' 向量
​
​
​
​
​
u = [uω′ −1 , uω′ −2 , uω′ −3 , ..., u1 , u0 ]
​
​
​
​
​
截断一个向量,当被截断的数字中含有 值为1的位时,向量所代表的值势必会改变。
ω > ω′
那么会有
u = B2Tω (u)
​
mod
u′ = B2Tω′ (u′ )
​
那么 有 u′ = u mod 2ω
′
求余运算
原理是截断从高位开始 被 截取的 k = ω − ω′ 位 所代表的权重依次是
[2w−1 , 2w−2 , ..., 2ω−k ]
它们对 2ω−k−1,也就是 2ω 施加 mod 运算的果都是 0,也就是相当于 截断了 k 位
′
(5)
公式太简单了不贴了 P57
)
5 signed truncate
的截断是先 xu = T 2Uω 转到 无符号 由无符号 x′u = xu mod 2ω 再转回 signed
signed x
U 2Tω′ (x′u )
​
′
​
​
​
​
​
就是这么简单,好像算法的特性 复杂的操作都可以由我们已经实现的简单操作的有限次组合去实现
9.Integer opration
由于数据类型字长的有限性,数据在运算时可能会超出其能够表示的范围,了解它们是如何进行运
算的能够让我们避免和发现这些错误(废话文学)以及如何纠正这些问题。
)
1 unsigned addiction
对于 两个数x,y 它们满足
0 ≤ x, y ≤ U M ax
那么它们的和
0 ≤ x, y ≤ 2ω+1 − 2
明显表示2ω+1 需要 ω + 1 位二进制 它所表示的向量已经超过了系统所规定的 ω位,最大值已经超
过了 UMax 那么就会无法表示 ,但是根据 unsigned 向量值解释的规则,虽然结果有 ω + 1位 只
会翻译 ω 位
那么这个操作其实就和我们的 truncate 操作一致 我们需要将 ω + 1 截断到 ω 位
同时我们定义一个运算符 +uw 表示 这个符号的左侧操作数是一个 unsigned 即(u) +符号的右侧
的操作数 它们的结果(位模式)按字长为 ω 去解释为数字
​
那么 x +uw y 如下
​
x +uw y = (x + y) mod 2ω
(6)
​
​ ​
那么其实对于 ω + 1 和 ω 直接减去 最高为结果是一致的 那么就有书上的 formula 2.11
U 2Tω = {
​
x+y
x + y − 2ω
x + y ≤ U M ax
x + y > U M ax
​
​
​
(7)
)
2 two's complement addiction
对于 两个数 signed x,y 它们满足
TM in ≤ x, y ≤ TM ax
那么它们的和
−2ω ≤ x, y ≤ 2ω − 2
那么依据一贯的作风,先 将 x,y 转为 unsigned 那么有
xu = T 2Uω (x) yu = T 2Uω (y)
​
​
​
​
然好是喜闻乐见的 以 unsigned 的格式进行计算(我想是因为无符号它们不需要考虑符号)而位模
式的计算是通用的,只是解释方式的变化,施加再 unsigned 上的 运算可以 通过 位模式 间接传递
到 two's complement 就好像是 two's complement 本身执行了计算一样。
那么有
xu +uω yu = (x + y) mod 2ω
​
​
然号 转回它们的结果到 two's complement
x +tω y = U 2Tω (xu +uω yu )
​
​
​
​
​
我们令
z =x+y
直接以位模式向加,和 xu +uω yu 是一致的,我们不解释它所代表的含义,单纯采用它们的位模
式
​
​
​
z ′ = x + y mod 2ω
截断到数据类型所要求的宽度
z ′′ = U 2Tω (z ′ )
​
以signed 的法则将位模式解释为数值
那么就会有有四种情况,x+y的范围是 −2ω ≤ x, y ≤ 2ω − 2 ,
我们先对两个数字的位模式进行加法运算,得到它们新的位模式 ,根据新位模式 我们进行截断 然
好回转到补码。我们需要注意到一些法则
z 为 负数和正数 进行求余运算的差异 ,若z>0 那么 z mod n =z-n 若 z<0 那么 z mod n=z+n; (
n = 2ω )
后者的例子
-5 mod 2=-3 (-5+2)
那么向加后的结果一共有四种情况
−2ω ≤ z < −2ω−1
截断两个无符号数相加结果 z′ = z mod 2ω
因为 z<0 所以z′ = z + 2ω 那么我们将这个被截断后的值向有符合时转化时参考我们 U T 2ω 的
规则
​
0 ≤ z ′ < 2ω−1
规则
x
U 2Tω = {
x − 2ω
​
​
x ≤ 2ω−1
x > 2ω−1
​
​
(8)
易得 U T 2ω (z′ ) = z′
所以
​
z ′′ = U 2Tω (z ′ ) = z ′ = z + 2ω = x + y + 2ω
​
剩下还有3种情况的判断方法也是一致,我们 取 z'' 最有可能发生变化的点 0, 2ω−1, 2ω 这些点那么
z 的取值范围依次是
−2ω−1 ≤ z < 0
0 ≤ z < 2ω−1
2ω−1 ≤ z < 2ω
那么我们根据 z 的范围取确定 z' 的范围 ,然后根据 U 2Tω 的规则 往 补码转
其实最后的最大值可以取到闭区间 2ω − 2
​
3
) f2.16 unisgned multiplication
有 unsigned x,y
0 ≤ x, y ≤ 2ω − 1
那么我们定义一个符合 表示两个无符号数相乘 ∗uω 那么 无符号数 x 和 y 的乘积的范围如下
​
0 ≤ x ∗uω y ≤ (2ω − 1)2
​
因为相乘后长度会超过无符号的上限
(2ω − 1)2 = 2ω2 − 2ω+1 + 1
​
= 2ω (22 − 21 ) + 1
= 2ω+1 + 1
所以 同样用求余运算截断 所以 x ∗uω y 的定义如下
​
​
​
(9)
x ∗uω y = (x ⋅ y) mod 2ω
​
)
4 two's complememt multiplication
有 用补码表示的两个 signed x,y
−2ω−1 ≤ x, y ≤ 2ω−1 − 1
同样使用符号 ∗tω 代表两个 补码的无符号数的乘法
那么先确定 x ⋅ y 的范围,很简单直接乘就行了,表达这个的结果极端情况下 需要 2ω 位所以需要
截断,同样我们把 T 转为 U 来计算 对结果进行 截断 后转回 T
​
还是我们 在计算时不关心 位模式所代表的值,我们只 关心 位模式的运算。
那么 signed umber x ,y 的乘法可以被定义如下
x ∗tω y = U 2T ((x ⋅ y) mod 2ω )
​
这里括号内的 x ⋅ y 不经过 T2U 直接使用的原因是我们只是用它的位模式来计算,不需要求解一
个有符号数 x 或者 y 所对应的 xu 或 yu
​
​
)
5 bit-level equivalence on multiplication
这里有一个证明,关于
T 2Bω (x ∗tω y) = U 2Bω (x′ ∗uω y ′ )
​
​
x′ = T 2Uω (x) x′ = x + 2ω xω−1
​
y ′ = T 2Uω (y) y ′ = y + 2ω yω−1
​
那么我们计算 x′ ∗uω y′
​
​
​
​
​
x′ ∗uω y ′ = [(x + 2ω xω−1 ) ⋅ (y + 2ω yω−1 ) mod 2ω ]
= (x ⋅ y) mod 2ω
​
​
​
​
​
​
(10)
大于 2ω 的权重都可以直接被舍去 我们只需要观察 x ⋅ y的结果和 2ω 的关系即可
此外我们根据 有符号数的乘法定义
x ∗tω y = U 2T ((x ⋅ y) mod 2ω )
​
对等式两边同时 取 T 2Uω
​
T 2Uω (x ∗tω y ) = T 2Uω (U 2T ((x ⋅ y) mod 2ω ))
= (x ⋅ y) mod 2ω
​
​
​
​
​
​
(11)
那么对 formula (10) 和 (11) 同时使用 *2B 转到位模式,很明显二者的等价性,那么也就是说。
虽然 无符号 和 有符号 乘法的结果它们在截断前的位模式可能不一致 ,但是在阶段后 二者是相
等的
)
6 multiply const
由于乘法指令需要的时钟周期比加法需要的时钟周期多,所以CPU 会尝试使用移位和加发操作来代
替乘法。
乘以 2ω 等价于 左移 k 位
假设存在 无符号数 u,它的位模式为 u 那么根据我们的 u = BT Uω (u) 那么
​
u ⋅ 2k = BT Uω (u) ⋅ 2k
​
w−1
​
= [ ∑ ui 2 i ] ⋅ 2 k
​
i=0
​
​
​
(12)
好像写错了.....是下面这个
w−1
BT Uω+k ([uω−1 , uω−2 , ..., u1 , u0 , 0..., 0]) = ∑ ui 2i+k
​
​
​
​
​
​
​
i=k
​
​
​
(13)
= u ⋅ 2k
求和中的 i=0 和 i=k 是一致的 因为 低 k 为是移位后被补位的
0
书上还说根据 无符号算术运算的位级别操作和 补码的算术运算的位级操作的等价性,所以补码乘
以常数同样使用 移位法则
在乘以不是 2k 这样的数字时,编译器会进行优化 将乘法操作 转化为等价的 操作 例如
u⋅n
等价于
假设 2k + ....2m + rest = n
u ⋅ n = u ⋅ (2k + ....2m + rest)
)
7 unsigned divide const
有 无符号数 x ,它的向量表示为x = [xω−1 , xω−2 , ..., x1 , x0 ]
x 右移动k 0 ≤ k ≤ ω 位后 它的位向量 x′ = [0, ..., 0, xω−1 , xω−2 , ..., xk ]
​
​
​
​
​
那么
ω−1
BT Uω (x) = ∑ 2i xi
​
​
i=0
​
​
​
又有
ω−1
BT Uω−k
​
= ∑ 2i−k xi
(x ′ )
​
​
i=0
​
= x ⋅ 2−k
x
= k
2
​
(14)
​
​
序号为 i 的权值 为 2i−k
那么 无符号数和 2的幂 的 除法 就可以转换为 右移 运算
对于补码表示,如果表示正数时,除以2的幂和无符号数一致(算术右移和逻辑右移 一致),但是
对于 负数由于 有符号数采用的是 算术右移 而无符号数 采用的是逻辑右移所以我们有不同的点需要
考虑
直接时用算术有移动可以得到可以接受的结果,但是结果总是趋向于向下舍入 例如
-12,在 8bit 那么 ω = 8表示 它的向量 −12 = [1, 1, 1, 1, 0, 1, 0, 0]
​
−12 ÷ 22 = [1, 1, 1, 1, 0, 1, 0, 0] >> 2
= [1, 1, 1, 1, 1, 1, 0, 1]
​
​
​
(15)
我们对这个结果进行 B2T8 ([1, 1, 1, 1, 1, 1, 1, 0])=-3
这似乎没有问题
​
我们试图尝试时用一个 不能由2 整除的数−13 = [1, 1, 1, 1, 0, 0, 1, 1]
那么 -13>> 2 就为 [1,1,1,1,1,1,0,0]=-4
那么实际的结果是 -3.25 那么我们更希望它的值是 -3 而不是 -4
所以在进行移位运算前需要对 -13加上一个偏置值进行修正,使得 x ÷ 2k 向更靠近自然运算的结
果的值进行舍入。
那里我,没看懂 在 p73
​
10.floating point number
由于计算机采用二进制而不是十进制,不同于我们在表示正数时可以使用不同的 2ω ω ∈ (0, ω)
的和来表示所有的十进制数,我们无法使用2−ω 的和来表示所有存在小数(数据类型的长度有
限),所以在计算机中 更高的精度意味着需要更长的数据宽度 。
)
1 binary decimal
定点表示小数
设一个小数 f 有位模式如下
f = [dm , dm−1 , dm−2 , .., d1 , d0 .d−1 , d−2 , d−k ]
​
​
​
​
​
​
​
​
​
那么
m
f = ∑ bi 2i
​
​
i=−k
那么 像 13 这种数字 需要无限个二进制位 取表示,通常在计算机会进行舍人到有限位,使用一个
近似值来表示。
又或者是在表示一个数字时,我们的整数部分很大(需要数据类型所持有的所有位才能表示),同
时这个数还存在小数位,那么我们只能选择忽略小数位,这样的误差在需要高精度计算的场景下无
疑是致命的。
​
)
2 IEEE 754
定点表示法有很多缺点,技术的高速发展往往是从标准被统一开始的。IEEE 协会 制定了浮点数的
标准,使用更短的数据宽度表示范围更大的小数集,它的定义如下
存在一个小数 F 它能够被表示为
F = (−1)s × M × 2E
数符S,确定了整个数字的符号
尾数M,F ÷ 2E 后的余数的可以表示被的值(经过舍入后可以被表示的最解决于自然运算结果的
值)它的范围是 0~1 − ϵ ϵ 是一个 无穷小 值
阶码E,对浮点数进行加权(正负权都可以)
那么一个浮点数的位模式被划分为 3 个部分
1. 符号
使用单独的一个 bit 承载符号的含义
2. 阶码
由长度为k的位模式表示(通常使用补码,需要表示负权)
3. 尾数
由n位二进制表示,它们如果不为0那么每位都携带权值。
那么就是如下
F = [s, ek−1 , ek−2 , ek−3 , ..., e1 , e0 , f0 , f1 , ..., fn−2 , fn−1 ]
​
​
​
​
​
​
​
​
​
规定 符号位s 占用1位,k=8,n=23 在32位时即使用4Byte 表示一个float 数字时,那么
在使用
表示一个数字时 s,k,n 分别是{1,11,52}
IEEE 775
8Byte
)
3 normalization
根据阶码的取值不同,将 浮点数F 分为 4个类型
1. 规格化的
当阶码 e 的位模式 即不也不全为0,1的情况,阶码 E 被解释为
E = e − Bias
是 unsigned,假设 e的宽度为 ω 那么 Bias = 2w−1 − 1 那么我们可以由此确定 E的范围
ω 位的无符号数的范围是
e
0 ≤ usingned ≤ 2w − 1
但是由于 e 既不能取到全0也不能取到全1所以
1 ≤ usingned ≤ 2w − 2
e-Bias
的范围是
1−
(2
w−1
−1
)≤e≤2
w
− 2 − (2w−1 − 1)
−2w−1 + 2 ≤ e ≤ 2w−1 − 1
这个值是一定能够使用 ω 位的补码来表示的
我想这样取偏置值的初衷是不是为了能够使用补码来表示
E
规格化的尾数部分 原始小数为 f 是在F减去 2k 的权之后的值,那么尾数被定义为
M =1+f
我们可以通过改变的值数来控制 M的值,使得尾数一定总是在 1 ≤ M < 2 之间那么小数点前一
位总是被我们限定为 1 所以我们可以不显现的写出,那么我们就可以多出一位来表示阶码或者尾
数。
我认为书上说的移动阶码取改变尾数因该是在 1+M 之前 移动阶码使得 f 的值总是在
0≤f <1
非规格化的
当阶码 e的位模式 全为0时,所表示的数是浮点数的非规格化的形式在这种情况下阶码 E 被定义为
2.
E = 1 − Bias
Bias = 2ω−1 − 1
那么E 必然是一个负数 那么根据浮点数的 加权规则 我们可以知道当 指数为负数时它的值越小那么
它越靠近 0。那么很明显一个非规格化的数字是很接近0的,也就意为着我们可以使用非规格化的
表示方法来表示那些 距离0非常近 的数。
非规格化的数字它的尾数被定义为
M =f
使用非规格化数我们可以表示规格化数所不能表示的 0(因为 规格化的尾数被定义为总是 大于
1),那么在非规格化变是形态中当尾数 f 为0 时整个浮点数就为0。
特殊值
当阶码e 的位模式 全为 1时 所表示的数即为特殊值,同时当阶码全1尾数的位模式 全为0 时 由符号
位来确定它的含义 符号位为 1 表示 +∞ 为0 则为 −∞ 若是尾数不全为0的数就不被认为是一个数
字的位模式的定义 N AN (Not A Number ),一些奇怪的运算会返回这样的结果诸如
3.
−1
​
∞−∞
得益于非规格化数字和规格化数 尾数的定义,它们可以在二者值域的交界处完成平滑的过渡。即从
非规格化数字的最大值可以平滑的像规格化的最小值过渡,那么我们来浅浅的证明一下
设e的位模式宽度为 ω 那么 Bias = 2ω−1 − 1
已知规格化数字的尾数定义为
E = e − Bias = e − 2ω−1 + 1
非规格化数字的尾数定义为
E = 1 − Bias = 1 − 2ω−1 + 1
那么可以很自然的发现,无论值数的位模式取任意宽度,当 e=1时,二者的阶码等价,此时规格化
数的阶码取得最小值1,那么当 f 为0 时尾数取 M = 1 + f 那么整个浮点数的值就为值数的权
值。而非规格化数的指数值被固定,它的值从最近0的位置向两侧均匀发散,当尾数f 的位模式取的
全 1时 尾数所表示的最大值值一定是 (假设尾数的位模式 采用 n位)
2n − 1
M=
2n
​
那么 V_irregular_max 会等于
2
2−2ω−1
2n − 1
⋅
2n
​
那么 V_ragular_min 会等于
22−2
ω−1
⋅1
那么它们的差是
22−2
ω−1
⋅
1
2n
​
通过观察它们二者只差了 指数的 21n 的倍数,这也是 n位尾数所能表示的最小的值了
​
书上说定义非规格化数 的值数为 1-Bias 可以补偿尾数尾数没有隐含的 1(P81) 看不懂捏,但
是平滑过渡还是可以理解的。
)
4 roundoff
由于浮点数在机器内部所采用的表示方法注定了浮点数不能完全精确的表示所有实数,只能使用近
似值来表示,对于一个我们需要表示的值 x 我们希望使用一个能够被计算机表示且最接近于 其真
实值的近似值来表示。这便是我们向向舍入工作所要求的。
例如我们永远无法使用期望的浮点数表示法 表示诸如 1.333333333 此类的数字,那么这个时候我
们就会使用到我们熟悉的舍入操作,那么我们根据需要截断的位数后的一位或多位来决定舍入后的
结果。就会存在多种舍入方式。
方式
向偶数舍入
向0舍入
向上舍入
向下舍入
1.40
1.60
1.50
2.50
-2.50
1
2
2
2
-2
1
1
1
2
-2
2
2
2
3
-2
1
1
1
2
-3
出了向偶数舍入其它的方式都很好理解,那么向偶数舍入的规则是这样的,对于一个数,它一定是
处于两个上下限的正中位置(诸如 1.5 之于 [1,2]),那么它的舍入方向取决于二者中的那个数字是
偶数。
那么对于正好位于两个数字中间的 数 进行舍入的规则并不是像看起来随意的那么随意的,它在一
定程度上保证了 平均值的准确性,因为当我们对这种 中位数 无论是采用向上还是向下舍人或者向
0舍入时毫无疑问它的变化是线性的,那么我们的平均值势必会偏离其本应该的值,而向偶数舍入
则不同,它的变化曲线是上下波动的(50%向上,50%向下),那么变化的量就会进行部分的相互
抵消,使得结果不会和实际的值出现极大的误差。
同样我们可以将这种舍入方法推广到非整数舍人,我们只需要根据最低有效位的奇偶来决定舍人的
方向。
如下例子,我们将把值舍入到两位小数。
标号
原始值
舍入后
舍人方法
a
1.2349999
1.23
b
1.2350001
1.24
c
1.2350000
1.24
d
1.2450000
1.24
向下
向上
偶数舍入
偶数舍入
对于 数a 它的值并不在我们要保留的 和其原始值 相关的2 位数([1.23,1.24]) 的正中间那么我们
对它采用最接近于真实值的舍人 即 1.23, 数b 同上,对于 数 c 位于 1.23 和1.24 之间 1.24的最
低有效位位偶数,所以选择向 1.24舍入 数d 同理
类似的我们可以将偶数的舍入方式推广到二进制小数的舍入,在这种舍入方法中,将0视为偶数将1
视为奇数,且只有独特的位模式才使用向偶数舍人
XX...X.YY ..Y 100...
表示任意的0或1,最右侧的Y是被舍入的位置,那么也就意为着只有 舍入位置的后一位是 1而的
全为0 才采用偶数舍人,因为只有这种位模式才表示这个数字正好在截断位置的两个数字
的中间位置。
XY
2 ∼ end
对下列数字舍入2−2 即
编号
原始值
舍入后
a
10.00011
10.00
b
10.00110
10.01
c
10.11100
11.00
d
10.10100
10.10
舍人方式
向下
向上
偶数
偶数
首先需要明确的是我们需要舍入的位置是 小数点后2位,对于数a 和 数 b 不需要过多的解释,对于
数 c 它的值是 2 7 ,那么它的前一个能够被表示的数值是 [10.11000] 2 6 ,它的下一个能被表示
8
8
​
​
的值是[11.00000] 2 88 那么从位模式的观察,我们可以发现到我们需要截断的 小数点后的第二
位是偶数的条件,很明显后者是我们的选择。
​
那么对于 数 d 它的值是 2 169 它的前一个能够表示的值是 [10.10000] 2 168 对于它的后一个能
够表示的值是 [10.11000] 2 148 那么明显我们要维持最低有效位为偶数的规则那么我们就选择
向前者舍入。
​
​
​
)
5 operation
对于两个浮点值 x,y IEEE 定义了一个运算规则 ⊙,那么任意运算 x ⊙ y 被执行为 round(x ⊙ t)
,它独立于任何具体的硬件,是一种抽象的规则。但是由于溢出和舍入一些在整数运算中的特性被
丢弃。
浮点数加法不具有结合性 即 有 三个浮点数 a,b,c 那么会出现
(a + b) − c =
 a + (b − c)
诸如
a = 3.14
b = 1e10 b = 1e10
显然 a + b 被执行为 round(3.14 + 1e10) 那么3.14会被舍去
浮点加法满足了单调性,对于 a ≥ b 那么对于任何除了 N aN 的 a,b 以及 x的值都有
x+a≥x+b
显然在整数的加法中由于溢出,不具有这个特性
浮点乘法具备结合性以及浮点乘法在加法上不具有分配性
不具备结合性
(1e20 ∗ 1e20) ∗ 1e − 20 =
 1e20 ∗ (1e20 ∗ 1e − 20)
在单精度下前者 为 ∞ 后者 为 1e20
在加法上的分配性
(1e20 − 1e20) ∗ 1e20 =
 (1e20 ∗ 1e20) − (1e20 ∗ 1e20)
前者的结果是 0 而后者无法被确认为一个浮点数的位模式
此外还有 对于任何的 a,b和c 都不等于 N AN 那么它们的乘法也具有 单调性
gpt 4.0
发布 不知道怎么说
Download