IEEE754浮点数标准学习

IEEE754浮点数标准学习

因为不太理解书上关于这一段的描述,可能是没有认真看,故写了这篇文章,边看边做记录。

浮点数的表示

当然在讲之前,我们首先讲一下关于浮点数的表示格式。对于任意的实数\(X\),可以表示为如下的形式
\[X=(-1)^S*M*R^E\]
其中,\(S\)的取值为0或者1,一般为0为正,1表示负数。
\(M\)是一个二进制定点整数,称为\(X\)的阶码或者指数
\(R\)是基数,可以约定俗称的设置为2,4,16等
要确定一个实数的值,只要在默认基数\(R\)下,确定数符\(S\)、尾数\(M\)和阶码\(E\)就可以了

举个具体的例子

将十进制数65798转换为IBM370的32位短浮点数格式。
第0位为数符S;
第1~7位为7位移码表示的阶码E;
第8~31位为6位十六进制原码小数表示的尾数M
阶码的偏置常数=64
\(R\)=16

解:
因为\((65789)_{10}=(10106)_{16}=(0.101060)_{16}*16^5\)
所以数符\(S=0\)
阶码\(E=(64+5)_{10}=(69)_{10}=(100 0101)_2\)
所以表示形式为如下
0 1000101 0001 0000 0001 0000 0011 0000
换成16进制即为
45 10 10 60H

对于给定的IBM370的32位浮点数的求解,就是这个编码过程的逆过程,步骤如下:

  • 数符\(S=0\),符号位正号
  • 阶码\(E=(1000101)_2=(64+5)_{10}\)
  • 尾数\(M=(101060)_{16}\)
  • 故原十进制数\(X=M^5=(65789)_{10}\)

以上就是浮点数表示的例子,但是在表示浮点数的时候要注意以下几点:

  • 0的表示问题
  • 浮点数的密度问题
  • 表示精度和表示范围的权衡

具体问题在教材中已经诠释的很清楚,这里不做赘述。

IEEE754浮点数标准

首先,对于IEEE754浮点数标准,目前几乎所有计算机都采用这个标准,并在这个标准中,提供了两种基本浮点数格式:

  • 32位单精度
  • 64位双精度
浮点数格式 符号 阶码 尾数
32位单精度格式 1 8 23
64位双精度格式 1 11 52

对于IEEE754标准,基数隐含为2。尾数用原码表示,第一位总为1,所以可以省略第一位,使得单精度的23位实际表示了24位,双精度的52位,实际表示了53位。

在这这里我有一个疑问,为什么第一位总为1?
我的理解:
因为基数隐含为2,所以对于任意的二进制正数的移码都可以被表现为如下的形式
\[1.XXX*2^M\]
对于所有的二进制数都可以表示为这样的形式

当然这个问题在接下来的一句话就说明了,IEEE754规定隐藏位1的位置在小数点之前
在在IEEE754标准中,阶码用移码表示,但偏置常数并不是通常n位移码所用的\(2^{n-1}\),而是\(2^{n-1}-1\),故而单精度的偏置常数为127,双精度的偏执常数为1023.
由于隐藏了小数点前1的原因,如果换成等值纯小数表示的话,阶码就需要加1.但是无论是哪一种,最终的计算结果和偏置常数的情况是相同的。并且,使尾数带一个隐藏位,有以下的两点好处

  • 尾数可以多一位,故精度可以更高
  • 阶码的表示范围可以更大,因而使浮点数的范围更大

具体的IEEE754各种数的解释,在书上已经列的非常详细了,对于规定的数,大概可以分类为如下:

  • 全0阶码全0尾数:+0/-0
    IEEE754的0有两种表示:+0和-0。0的符号取决于数的符号位s。一般情况下是等效的。

  • 全0阶码非0尾数:非规格化数
    非规格化数的特点就是阶码部分全为0,尾数的高位有一个或者连续几个0,但不全为0。因为隐藏位为0,并且单精度和双精度浮点数的阶码的值分别为-126或者-1022,故数值可以为

\[(-1)^{s}*0.f*2^{-126}\]
或者,
\[(-1)^{s}*0.f*2^{-1022}\]

非规格数的意义在于可以处理阶码下溢,使得出现比最小规格化数还小的数还能继续进行下去。

为什么能处理阶码下溢?
因为规格化数的表现形式为
设阶码为\(e\),以单精度举例,则规格化非零整数表示的值为\(2^{e-127}*(1.f)\)
显然当\(e=1\)时,有最小\(2^{-126}*(1.f)\)
而非规格化整数则为\(2^{-126}*(0.f)\)
显然能表示更小的数

非规格化数可用于处理阶码下溢,使得出现比最小规格化数还小的数时程序也能继续进行下去。简而言之就是尾数向右移动,阶码加1.

当一个十进制运算系统的最小阶码为-99时,有以下过程:

\(2.0000*10^{-26}*5.2*10^{-84}\)
\(=1.04*10^{-109}\)
\(0.104*10^{-108}\)
\(0.0104*10^{-107}\)
\(0.0010*10^{-106}\)
\(0.0001*10^{-105}\)
\(0.0000*10^{-104}\)
\(0.0\)

以上就是一个逐级下溢的过程

  • 全1阶码全0尾数:+∞/-∞
    引入无穷大和无穷小使得在计算过程出现异常的情况下计算可以继续下去,并且可以提供错误检测的功能。+∞在数值上大于所有有限数,-∞则小于所有有限数,无穷大数既可作为操作数,也可能是运算的结果。当操作数为无穷大时,系统可以有两种处理方式。
    • 产生不发信号的非数NaN
      如+∞+(-∞),+∞-(+∞),∞/∞等。
    • 产生明确的结果
      如5+(+∞)=+∞,(+∞)+(+∞)=+∞,5-(+∞)=-∞,(-∞)-(+∞)=-∞等
  • 全1阶码非0尾数:NaN(Not a Number)
    表示没有定义的数,称为非数。分为不发信号和发信号两种。
    可以用非数表示每个变量的非初始化值

  • 阶码非全0且非全1:规格化非0数

以上就是书上内容的简略内容,不知是否表述清楚,但是在边做笔记边看书后,我确实能够比较好的理解IEE754编码。

以下举具体的计算实例。

将十进制数-0.75转换为IEEE754的单精度浮点数格式表示

解:
\((-0.75)_{10}=(-0.11)_2=(-1.1)_2*2^{-1}\)
所以\(s=1,f=0.100...0,e=(127-1)_{10}=(01111110)_2\)
规格化的表示方法为
1 0111 1110 1000 0000 0000 000 0000 000
16进制表示为
BF 40 00 00H

猜你喜欢

转载自www.cnblogs.com/woshiwangtongxue/p/12418750.html