红魔咖啡馆

头发越掉越多,头发越掉越少

0%

【计算机组成原理】浮点数

Floating Point

二进制小数(定点表示)

对于十进制表示, 小数点左边对应的数的权值为10的正幂,右边对应的权值为10的负幂 则二进制也可以用该方式表示,即小数点左边的位的权是2的正幂,右边的位的权是2的负幂,用公式表示为\(b=\displaystyle\sum^{m}_{i=-n} 2^i\times b_i\) 从公式中容易看出,二进制小数点左移一位相当于这个数被2除,右移一位相当于将这个数乘2 形如0.11…11的二进制小数表示刚好小于1的数,可以用1.0-\(\epsilon\)来表示这种值 考虑有限长度的编码,二进制表示法只能表示那些能被写成\(x\times 2^y\)的数,其他值只能近似表示

\(\frac{1}{10}\)的二进制表示为0.0001100110011[0011]…

简单换算方法:将一个数表示为形似\(\frac{x}{2^k}\)的分数形式,将x用二进制表示,然后将小数点插入从右算起的第k个位置

浮点表示法

浮点表示法通过移动二进制小数点来表示尽可能大的范围,同时兼顾精度

IEEE浮点标准使用\(V=(-1)^s\times M\times 2^E\)的形式来表示一个数 - 符号:s决定是负数(s=1)还是正数(s=0),数值0的符号位解释作为特殊情况处理

  • 尾数:M是一个二进制小数,范围为1至2-\(\epsilon\)或0至1-\(\epsilon\)

  • 阶码:E的作用是对浮点数加权,权为2的E次幂,用于扩大或缩小尾数值 将浮点数的位表示划分为三个字段,分别编码:

  • 一个单独的符号位s直接编码s

  • k位的阶码字段exp编码阶码E

  • n位小数字段frac编码尾数M,编码出来的值也依赖于阶码字段的值是否为0 单精度浮点下,k=8位,n=23位,得到一个32位表示 双精度浮点下,k=11位,n=52位,得到一个64位表示

给定位表示,根据exp的值,被编码的值可以分为三种不同的情况: ### 规格化的值 当exp的位模式既不全为0,也不全为1(单精度为255,双精度为2047),都属于这种情况,这种情况下:

阶码字段被解释为以偏置形式表示的有符号整数,值为\(E=e-Bias\),其中e为无符号数,\(Bias=2^{k-1}-1\)(单精度下为127,双精度下为1023),这样将有符号的指数位全迁移到了正区间,方便大小比较

小数字段被解释为描述小数值\(f(0\leq f<1)\),二进制小数点在最高有效位的左边,尾数定义为\(M=1+f\),也称隐含的以1开头的表示,因此可以把M看作一个二进制表示为\(1.f_{n-1}f_{n-2}\cdots f_0\)的数字

  • 当frac全为0时,有最小值M=1.0
  • 当frac全为1时,有最大值M=2.0-\(\epsilon\)

非规格化的值

当阶码域全为0时,表示的数是非规格化形式,这种情况下,阶码值为\(E=1-Bias\),尾数的值是\(M=f\),即小数字段的值,不包含隐含的开头的1

非规格化的值有两个用途:

  1. 用来表示数值0,因为规格化值要求下\(M\geq1\),不能表示0

    但是对于+0.0,它的位模式为全0,而-0.0的符号位是1,其余位全为0,因此在某些方面,这两个书被认为是不同的,而在其他方面是相同的

  2. 用于表示那些非常接近于0.0的数,它们提供了一种属性称为逐渐下溢,可能的数值分布均匀地接近于0.0

特殊值

当阶码全为1,小数域全为0时,得到的值表示无穷,\(s=0\)时是\(+\infin\)\(s=1\)时是\(-\infin\),当我们把两个非常大的数相乘或除以0时,使用无穷来表示溢出的结果。

当阶码全为1,小数域为非0时,结果值表示NaN(Not a Number),一些运算的结果不能是实数或无穷时,或表示未初始化的数据时可以使用

重要浮点数的表示

  • +0.0总有一个全为0的位表示

  • 最小的正非规格化值的位表示是由最低有效位为1而其他所有位为0构成的,其\(M=f=2^{-n}\)\(E=-2^{k-1}+2\),故数字值为\(V=2^{-n-2^{k-1}+2}\)

  • 最大的非规格化值的为模式是由全为0的阶码字段和全为1的小数字段组成的,其\(M=f=1-2^{-n}\)(写作\(1-\epsilon\)),\(E=-2^{k-1}+2\),故数字值为\(V=(1-2^{-n})\times2^{-2^{k-1}+2}\),比最小规格化数小一点点

  • 最小的正规格化值的位模式阶码字段的最低有效位为1,其他位全为0,其\(M=1\)\(E=-2^{k-1}+2\),因此数值\(V=2^{-2^{k-1}+2}\)

  • 值1.0的位表示解码字段除了最高有效位为0外,所有其他都等于1,其\(M=1\), \(E=0\)

  • 最大的规格化值的位表示的符号位为0,阶码最低有效位为0,其他位为1。 其\(f=1-2^{-n}\)\(M=2-2^{-n}\)(写作\(2-\epsilon\)),\(E=2^{k-1}-1\),因此数值\(V=(1-2^{-n-1})\times 2^{2^{k-1}}\)

整数值转换浮点形式

例:12345具有二进制表示[11000000111001],将二进制小数点左移13位,得到规格化表示\(12345=1.1000000111001_2\times 2^{13}\),为了使用IEEE单精度表示,丢弃开头的1并在末尾增加10个0来构造小数字段,得到二进制[10000001110010000000000],构造阶码字段,用13加偏置值127,得到140[10001100],加上符号位0,得到二进制浮点表示[01000110010000001110010000000000]

再对12345和12345.0进行比较

关系

发现相关区域对于整数的地位,正好在最高有效位1前停下,和浮点表示小数部分的高位相匹配,其中这个最高有效位1就是隐含的开头的位1

舍入

由于表示方法限制了浮点数的范围与精度,所以浮点数只能近似地表示实数运算,因此舍入可以找到一个值x最接近的匹配值x’

IEEE浮点格式定义了四种不同的舍入方式,默认的方法是找到最接近的匹配,而其他三种可以用于计算上下界

其中向偶数舍入(向最接近的值舍入)是默认的方式,试图找到一个最接近的匹配值,采用的方法为:将数字向上或向下舍入,使得结果的最低有效数字是偶数,如1.5和2.5都被舍入为2

具体的,若一个小数要精确的位数后面类似于xxx5000…(后面全是0),此时要看前一位是奇还是偶,向偶数舍入。而若后面的大于5则向上舍入,小于5则向下舍入,如:

  • 7.894999:小于.xx5000,向下舍入为7.89
  • 7.895001:大于.xx5000,向上舍入为7.90
  • 7.895000:等于.xx5000,向偶数舍入为7.90
  • 7.885000:等于.xx5000,向偶数舍入为7.88

也可以用于二进制小数,将最低有效位的值0认为是偶数,1认为是奇数,一般来说,只有对形如XX…X. YY…Y100…的二进制位模式的数(即舍弃的那位为1,后面都为0),这种舍入方式才有效,其中X与Y表示任意位值,最右边的Y是要被舍入的位置。而大于100…向上舍入,小于100…向下舍入,如(舍入有效位4位):

  • 10.00011:小于xx100,向下舍入为10.00=2
  • 10.00110:大于xx100,向上舍入为10.01=2.25
  • 10.11100:等于xx100,向偶数舍入为11.000=3
  • 10.10100:等于xx100,向偶数舍入为10.10=2.5

其他三种方式:向零舍入、向下舍入、向上舍入产生实际值的确界

  • 向零舍入把正数向下舍入,把负数向上舍入,得到\(|\hat{x}|\leq|x|\)
  • 向下舍入把正数和负数都向下舍入,得到\(x^-\leq x\)
  • 向上舍入把正数和负数都向上舍入,得到\(x^+\geq x\)

浮点运算

IEEE标准指定了一个简单的规则,将浮点数x与y看作实数,某个运算\(\odot\)定义为\(Round(x\odot y)\),即对实际运算的精确结果进行舍入后的结果

当参数中有一个是特殊值(-0,\(-\infin\)或NaN)时,IEEE标准定义了一些更合理的规则,如\(\frac{1}{0}=-\infin\)\(\frac{1}{+0}=+\infin\)

运算性质

实数的加法也形成了阿贝尔群,但必须考虑舍入的影响,将\(x+^fy\)定义为\(Round(x+y)\)这个运算是可交换的,但不可结合。作为阿贝尔群,大多值在浮点加法下都有逆元,即\(x+^f-x=0\),无穷和NaN例外

另一方面,浮点加法满足了单调性属性:若\(a\geq b\),那么对于任何a、b以及x的值,除了NaN,都有\(x+a\geq x+b\)

对于浮点乘法,同样可交换但不能结合,对于任何a、b和c都不为NaN,满足单调性:

  • \(a\geq b且c\geq0 \Rightarrow a\times^fc\geq b\times^fc\)
  • \(a\geq b且c\leq0 \Rightarrow a\times^fc\leq b\times^fc\)
  • 并且保证只要\(a\neq NaN\),就有\(a\times^fa\geq0\)

比较运算

对于浮点数间的比较,除了NaN,其余浮点数间都可以互相比较,包括inf(将其视为无符号)

  • 首先比较符号位
  • \(-0=0\)
  • NaN大于其余任何值
  • 其余均可以比较,包括规格、非规格、无穷大

乘法

\(V_1=(-1)^{s_1}\times M_1\times 2^{E_1}\)\(V_2=(-1)^{s_2}\times M_2\times 2^{E_2}\)相乘,得到的结果\(V=(-1)^{s}\times M\times 2^{E}\)

  • \(s=s_1\oplus s_2\)
  • \(M=M_1\times M_2\)
  • \(E=E_1+E_2\)

修正:

  • \(M\geq2\),右移M到范围内,增加E
  • 若E超出范围,则溢出
  • 舍入M至让frac能准确表示

加法

\(V_1=(-1)^{s_1}\times M_1\times 2^{E_1}\)\(V_2=(-1)^{s_2}\times M_2\times 2^{E_2}\)相加,得到的结果\(V=(-1)^{s}\times M\times 2^{E}\)(假设\(E_1>E_2\)

  • 将二进制小数点对齐
  • s与M均为直接相加
  • \(E=E_1\)

修正:

  • \(M\geq2\),右移M到范围内,增加E
  • \(M<1\),左移k位M,减小k的E
  • 若E超出范围,则溢出
  • 舍入M至让frac能准确表示

C语言中的浮点数

C语言提供了单精度浮点float与双精度浮点double,使用向偶数舍入

但C语言标准不要求机器使用IEEE浮点,故没有标准方法改变摄入方式或得到特殊值

当在int,float与double间进行强制类型转换时,程序改变数值和位模式的原则如下:

  • 从int转为float:不会溢出,可能被舍入
  • 从int或float转换成double:能保留精确数值
  • 从double转换成float:值可能溢出或舍入
  • 从float或double转换成int:向零舍入,可能会溢出