浮点数规范(IEEE754)

  本文主要参考《IEEE Standard for Floating-Point Arithmetic》

名词解释:
significand(有效位):A component of a finite floating-point number containing its significant digits. The significand can be thought of as an integer, a fraction, or some other fixed-point form, by choosing an appropriate exponent offset. A decimal or subnormal binary significand can also contain leading zeros.

1. Floating-point formats

浮点数格式

1.1 Specification levels

规范等级

  浮点算术是对于实际算术的系统近似,如表1.1所示。浮点算术只能表示连续实数的一个有限子集。因此对于实数的某些属性(例如加法结合律(associativity of addition)),并不总是适用于浮点算术。

表1.1 规范化等级及其格式
Level 1 {    0    +}\{-\infty \; \ldots \; 0 \; \ldots\; +\infty\} 扩展实数
多对一 ↓↓ 舍入 ↓↓ ↑↑ 映射(除了NaN
Level 2 {0}    {+0+}  \{-\infty \ldots -0 \}\; \bigcup \; \{+0 \ldots +\infty \} \; \bigcup NaN 浮点数据 - - 代数封闭的系统
一对多 ↓↓ 规范化表示 ↓↓ ↑↑ 多对一
Level 3 (sign,exponent,significand)    {,+}  (sign, exponent, significand) \; \bigcup \; \{-\infty,+\infty \} \; \bigcup qNaN \bigcup sNaN 浮点数据的表示
一对多 ↓↓ 浮点数据的编码表示↓↓ ↑↑ 多对一
Level 4 01110000111000\ldots 比特字符串(Bit strings)

   在该标准中,支持算术的数据格式是扩展实数,即实数集以及正负无穷( {0+}\{-\infty \ldots 0 \ldots+\infty\})。对于给定的格式,舍入过程(见后面第?节)将扩展的实数映射到该格式中的浮点数。浮点数据可以是带符号的零,有限的非零数字,带符号的无穷大或NaN,可以以一种格式映射到一个或多个浮点数据表示形式。

   浮点数据的表示格式(就是Level 3)包括以下3大部分:

  • 三元组(sign,exponent,significand)(sign, exponent, significand)
    对于基数bb,用三元组表示的浮点数就是 (1)sign×bexponent×significand\LARGE (-1)^{sign} {\times} b^{exponent}{\times}significand
  • ,+-\infty,+\infty
  • qNaN(quiet,不抛异常),sNaN(signaling,抛异常)

  encoding将浮点数据的表示映射为比特字符串。encoding可能会将一些浮点数据映射到多个比特字符串。应该使用多个NaN比特字符串来存储回顾性诊断信息(见后面第?节)。


1.2 Sets of floating-point data

浮点数据集

  有限的浮点数集合可以用特定的格式表示,由以下整数参数决定:

  • b\Large b:基数,2或者10。
  • p\Large psignificandsignificand(有效位)中数字的个数。(precision精度)
  • emax\Large emax:最大指数ee
  • emin\Large emin:最小指数ee
    对于所有格式,eminemin 应为 1emax1-emax

   对于每种基础格式,以上参数的值都在表1.2中给出了。

表1.2
二进制格式(b=2) 十进制格式(b=10)
参数 二进制32 二进制64 二进制128 十进制64 十进制128
p 24 53 113 16 34
emax +127 +1023 +16383 +384 +6144

   浮点数据统一表示形式:

  • 有符号和非零的浮点数格式为 (1)s×be×m\LARGE (-1)^{s} \times b^e \times m ,其中
    • ss是0或者1
    • ee是任意整数,emineemaxemin \leqslant e \leqslant emax
    • mm是一个数字,用一个比特字符串表示,该字符串格式如下:
      d0d1d2...dp1d_0\cdot d_1d_2...d_{p-1},其中did_i是一个整数数字满足0di<b0 \leqslant d_i <b(因此0m<b0 \leqslant m <b这里其实我不太懂
  • 两个无限值,++\infty-\infty
  • 两个 NaNsqNaN和sNaN

   m为整数时:

  在上述描述中,符号mm被视为一种科学形式,小数点紧接在第一个数字之后。为了某些目的,把 significandsignificand 看作一个整数也很方便,在这种情况下有限浮点数的表示如下:

  • 有符号和非零的浮点数格式为 (1)s×bq×c\Large (-1)^{s} \times b^q \times c ,其中
    • ss是0或者1
    • qq是任意整数,eminq+p1emaxemin \leqslant q+p-1 \leqslant emax
    • cc是一个数字,用一个比特字符串表示,该字符串格式如下:
      d0d1d2...dp1d_0d_1d_2...d_{p-1},其中did_i是一个整数数字满足0di<b0 \leqslant d_i <b(因此cc是一个整数,0c<bp0 \leqslant c <b^p

  这种表示把 significandsignificand 当做一个整数 cc,对应的 exponentexponentqq。(对于有限浮点数,e=q+p1e=q+p-1m=c×b1pm=c\times b^{1-p}


  最小的正normal(正规数)浮点数是 beminb^{emin} ,最大的是 bemax×(bb1p)b^{emax}\times (b-b^{1-p}) 。对于这种格式化的非零浮点数,量级小于beminb^{emin}的被称为subnormal(次正规数),因为它的量级在零和最小正规数的量级之间。他们的有效位数(significandsignificand digits)通常比 pp 要少。每一个有限浮点数字都是最小次正规数的整数倍 bemin×b1pb^{emin}\times b^{1-p}

  对于值为0的浮点数,符号位 ss 提供了额外的信息位。尽管所有格式对 +0+00-0 都有不同的表示,但 00 的符号在某些情况下很重要,比如 00 除以xxx,但在其他情况下则不重要(后面再讲)。二进制转换格式对于 +0+00-0 只有一种表示,但是十进制格式有很多。在此标准中,当符号不重要时,00\infty 不带符号。


1.3 Binary interchange format encodings

二进制转换格式编码

  每个浮点数只有一种二进制交换格式的编码。为了使编码具有唯一性,对于1.2中的参数,通过减小 ee 使有效位(significand)mm 的值最大化,直到 e=emine=eminm1m\geqslant1。这个过程完成后,如果 e=emine=emin0<m<10<m<1 ,则浮点数为次正规数(subnormal)。次正规数(以及零)用一个表留的偏置指数值来编码。(Subnormal numbers (and zero) are encoded with a reserved biased exponent value)

  浮点数的二进制形式由 kk 个比特的编码表示,主要有3个部分:

  1. 1个比特,符号位S
  2. w个比特,偏置的指数(biased exponent),E=e+biasE=e+bias
  3. (t=p-1)个比特,尾部有效位(trailing significand field)数字字符串 T=d1d2...dp1T=d_1d_2...d_{p-1}

浮点数规范(IEEE754)

  二进制转换格式的 k,  p,  t,  w,  biask, \; p,\; t,\; w,\; bias 的值如表1.3所示

表1.3 二进制交换格式的参数
参数 二进制16 二进制32 二进制64 二进制128 二进制kk (k128)(k\geqslant128)
kk,数据宽度 16 32 64 128 32的倍数
pp,精度 11 24 53 113 kround(4×log2(k))+13k-round(4\times log_2(k))+13
emaxemax,指数ee的最大值 15 127 1023 16383 2(kp1)12^{(k-p-1)}-1
biasbiasEeE-e 15 127 1023 16383 emaxemax
符号位 1 1 1 1 1
ww,指数位的宽度 5 8 11 15 round(4×log2(k))13round(4\times log_2(k))-13
tt,尾部有效位的宽度 10 23 52 112 kw1k-w-1
kk,数据宽度 16 32 64 128 1+w+t1+w+t

这里roundround表示四舍五入


  编码中偏置的指数项 EE 应该包括:

  • 包含 [1,2w2][1,2^w-2] 的每个整数,用于编码规范数(normal numbers)
  • 保留值 00 ,用于编码 ±0\pm0 和次规范数(subnormal numbers)
  • 保留值 2w12^w-1 ,用于编码 ±\pm\inftyNaNs

  浮点数据的表示形式 rr ,以及浮点数据代表的值 vv ,由组合字段推断出来,如下所示:

(a) 如果 E=2w1E=2^w-1,并且 T0T\neq0 , 则 rr 就是 qNaN 或者 sNaNvv 就是 NaN(无论符号位)

(b) 如果 E=2w1E=2^w-1,并且 T=0T=0 , 则 rrvv 都是 (1)S×(+)\large(-1)^S\times(+\infty)

(c) 如果 1E2w21\leqslant E \leqslant2^w-2,则 rr 就是 (S,(Ebias),(1+21p×T))\large(S, (E-bias),(1+2^{1-p}\times T))
对应的浮点数的值v=(1)S×2Ebias×(1+21p×T)\large v=(-1)^S\times 2^{E-bias}\times(1+2^{1-p}\times T)

(d) 如果 E=0E=0,并且 T0T\neq0,则rr就是(S,emin,(0+21p×T))\large(S, emin,(0+2^{1-p}\times T))
对应的浮点数的值v=(1)S×2emin×(0+21p×T)\large v=(-1)^S\times 2^{emin}\times(0+2^{1-p}\times T)

(e) 如果 E=0E=0,并且 T=0T=0,则 rr 就是(S,emin,0)\large(S,emin,0)vv就是 v=(1)S×(+0)\large v=(-1)^S\times (+0)


注意,kk是64或以上(32的倍数)时,下面的式子成立:
k=1+w+t=w+p=32×ceiling((p+round(4×log2(p+round(4×log2(p))13))13)/32)k=1+w+t=w+p=32\times ceiling((p+round(4\times log_2(p+round(4\times log_2(p))-13))-13)/32)
w=kt1=kp=round(4×log2(k))13w=k-t-1=k-p=round(4\times log_2(k))-13
t=kw1=p1=kround(4×log2(k))+12t=k-w-1=p-1=k-round(4\times log_2(k))+12
p=kw=t+1=kround(4×log2(k))+13p=k-w=t+1=k-round(4\times log_2(k))+13
emax=bias=2(w1)1emax=bias=2^{(w-1)}-1
emin=1emax=22(w1)emin=1-emax=2-2^{(w-1)}


1.4 Decimal interchange format encodings

十进制转换格式编码

有空再说


1.5 Extended and extendable precisions

扩展的和可扩展的精度

有空再说


2. 举个例子

2.1 编码的浮点数转十进制小数

  假设内存中存了一个32位浮点数,十六进制:0x40680000,二进制:0b01000000011010000000000000000000
  图示如下:

浮点数规范(IEEE754)
根据上面的 [表1.3] 可得:
p=24p=24bias=127bias=127w=8w=8t=23t=23

这里EE是二进制的10000000,即十进制的128,满足1E2w21\leqslant E \leqslant2^w-2,可以套公式v=(1)S×2Ebias×(1+21p×T)\large v=(-1)^S\times 2^{E-bias}\times(1+2^{1-p}\times T)

v=(1)0×2128127×(1+2124×11010000000000000000000)\large v=(-1)^0\times 2^{128-127}\times(1+2^{1-24}\times 11010000000000000000000)

由于这里是二进制,乘以2n2^n就是小数点向右移动nn个位,若nn是负数则向左移动nn个位。

于是v=1×2×(1+0.101)=1×2×1.1101)=11.101\large v=1 \times 2 \times(1+0.101)=1 \times 2 \times1.1101)=11.101

再转为十进制:v=21+20+21+23=3.625\large v=2^1+2^0+2^{-1}+2^{-3}=3.625