本文主要参考《IEEE Standard for Floating-Point Arithmetic》
看多几次就懂了,主要看它的表示形式和转换公式。
浮点数格式
规范等级
浮点算术是对于实际算术的系统近似,如表1.1所示。浮点算术只能表示连续实数的一个有限子集。因此对于实数的某些属性(例如加法结合律(associativity of addition)),并不总是适用于浮点算术。
Level 1 | { − ∞ … 0 … + ∞ } \{-\infty \; \ldots \; 0 \; \ldots\; +\infty\} { −∞…0…+∞} |
扩展实数 |
多对一 ↓↓ | 舍入 ↓↓ | ↑↑ 映射(除了NaN) |
Level 2 | { − ∞ … − 0 } ⋃ { + 0 … + ∞ } ⋃ \{-\infty \ldots -0 \}\; \bigcup \; \{+0 \ldots +\infty \} \; \bigcup { −∞…−0}⋃{ +0…+∞}⋃ NaN |
浮点数据 - - 代数封闭的系统 |
一对多 ↓↓ | 规范化表示 ↓↓ | ↑↑ 多对一 |
Level 3 | ( s i g n , e x p o n e n t , s i g n i f i c a n d ) ⋃ { − ∞ , + ∞ } ⋃ (sign, exponent, significand) \; \bigcup \; \{-\infty,+\infty \} \; \bigcup (sign,exponent,significand)⋃{ −∞,+∞}⋃ qNaN ⋃ \bigcup ⋃ sNaN |
浮点数据的表示 |
一对多 ↓↓ | 浮点数据的编码表示↓↓ | ↑↑ 多对一 |
Level 4 | 0 … 0\ldots 0111000… | 比特字符串(Bit strings) |
在该标准中,支持算术的数据格式是扩展实数,即实数集以及正负无穷( { − ∞ … 0 … + ∞ } \{-\infty \ldots 0 \ldots+\infty\} {
−∞…0…+∞})。对于给定的格式,舍入过程(见后面第?节)将扩展的实数映射到该格式中的浮点数。浮点数据可以是带符号的零,有限的非零数字,带符号的无穷大或NaN,可以以一种格式映射到一个或多个浮点数据表示形式。
浮点数据的表示格式(就是Level 3)包括以下3大部分:
- 三元组 ( s i g n , e x p o n e n t , s i g n i f i c a n d ) (sign, exponent, significand) (sign,exponent,significand); 对于基数 b b b,用三元组表示的浮点数就是 ( − 1 ) s i g n × b e x p o n e n t × s i g n i f i c a n d \LARGE (-1)^{sign} {\times} b^{exponent}{\times}significand (−1)sign×bexponent×significand
- − ∞ , + ∞ -\infty,+\infty −∞,+∞
- qNaN(quiet,不抛异常),sNaN(signaling,抛异常)
“浮点数的编码”将浮点数据的表示映射为比特字符串。“编码”可能会将一些浮点数据映射到多个比特字符串。应该使用多个NaN比特字符串来存储回顾性诊断信息(见后面第?节)。
浮点数据集
有限的浮点数集合可以用特定的格式表示,由以下整数参数决定:
对于每种基础格式,以上参数的值都在表1.2中给出了。
二进制格式(b=2) | 十进制格式(b=10) | ||||
---|---|---|---|---|---|
参数 | 二进制32位 | 二进制64位 | 二进制128位 | 十进制64位 | 十进制128位 |
p | 24 | 53 | 113 | 16 | 34 |
emax | +127 | +1023 | +16383 | +384 | +6144 |
浮点数据表示形式:
============================
(1)============================
- 有符号和非零的浮点数格式为 ( − 1 ) s × b e × m \LARGE (-1)^{s} \times b^e \times m (−1)s×be×m ,其中
- s s s是0或者1
- e e e是任意整数, e m i n ⩽ e ⩽ e m a x emin \leqslant e \leqslant emax emin⩽e⩽emax
- m m m是一个数字(小数),用一个比特字符串表示,该字符串格式如下:
d 0 . d 1 d 2 . . . d p − 1 d_0. d_1d_2...d_{p-1} d0.d1d2...dp−1,其中 d i d_i di是一个整数数字满足 0 ⩽ d i < b 0 \leqslant d_i <b 0⩽di<b(因此 0 ⩽ m < b 0 \leqslant m <b 0⩽m<b)- 两个无限值, + ∞ +\infty +∞和 − ∞ -\infty −∞
- 两个 NaNs,qNaN和sNaN
在上述描述中,符号 m m m被视为一种科学形式,小数点紧接在第一个数字之后。
============================
(2)============================
为了某些目的,把 s i g n i f i c a n d significand significand 看作一个整数也很方便,当 m m m 为整数时(各种进制的整数):
- 有符号和非零的浮点数格式为 ( − 1 ) s × b q × c \LARGE(-1)^{s} \times b^q \times c (−1)s×bq×c ,其中
- s s s是0或者1
- q q q是任意整数, e m i n ⩽ q + p − 1 ⩽ e m a x emin \leqslant q+p-1 \leqslant emax emin⩽q+p−1⩽emax
- c c c是一个数字,用一个比特字符串表示,该字符串格式如下:
d 0 d 1 d 2 . . . d p − 1 d_0d_1d_2...d_{p-1} d0d1d2...dp−1,其中 d i d_i di是一个整数数字满足 0 ⩽ d i < b 0 \leqslant d_i <b 0⩽di<b(因此 c c c是一个整数, 0 ⩽ c < b p 0 \leqslant c <b^p 0⩽c<bp)
这种描述把 s i g n i f i c a n d significand significand 当做一个整数 c c c,对应的 e x p o n e n t exponent exponent 为 q q q。(对于有限浮点数, e = q + p − 1 e=q+p-1 e=q+p−1, m = c × b 1 − p m=c\times b^{1-p} m=c×b1−p)
最小的正normal(正规数)浮点数是 b e m i n b^{emin} bemin ,最大的是 b e m a x × ( b − b 1 − p ) b^{emax}\times (b-b^{1-p}) bemax×(b−b1−p) 。对于这种格式化的非零浮点数,量级小于 b e m i n b^{emin} bemin的被称为subnormal(次正规数),因为它的量级在零和最小正规数的量级之间。他们的有效位数( s i g n i f i c a n d significand significand digits)通常比 p p p 要少。每一个有限浮点数字都是最小次正规数的整数倍 b e m i n × b 1 − p b^{emin}\times b^{1-p} bemin×b1−p。
对于值为0的浮点数,符号位 s s s 提供了额外的信息位。尽管所有格式对 + 0 +0 +0 和 − 0 -0 −0 都有不同的表示,但 0 0 0 的符号在某些情况下很重要,比如 0 0 0 除以xxx,但在其他情况下则不重要(后面再讲)。二进制转换格式对于 + 0 +0 +0 和 − 0 -0 −0 只有一种表示,但是十进制格式有很多。在此标准中,当符号不重要时, 0 0 0 和 ∞ \infty ∞ 不带符号。
浮点数据的“二进制转换格式”编码
每个浮点数只有一种二进制交换格式的编码。为了使编码具有唯一性,对于1.2中的参数,通过减小 e e e 使有效位(significand) m m m 的值最大化,直到 e = e m i n e=emin e=emin 或 m ⩾ 1 m\geqslant1 m⩾1。这个过程完成后,如果 e = e m i n e=emin e=emin 且 0 < m < 1 0<m<1 0<m<1 ,则浮点数为次正规数(subnormal)。次正规数(以及零)用一个表留的偏置指数值来编码。(Subnormal numbers (and zero) are encoded with a reserved biased exponent value)
浮点数的二进制形式由 k k k 个比特的编码表示,主要有3个部分:
二进制转换格式的 k , p , t , w , b i a s k, \; p,\; t,\; w,\; bias k,p,t,w,bias 的值如表1.3所示
参数 | 二进制16位 | 二进制32位 | 二进制64位 | 二进制128位 | 二进制 k k k位 ( k ⩾ 128 ) (k\geqslant128) (k⩾128) |
---|---|---|---|---|---|
k k k,数据宽度 | 16 | 32 | 64 | 128 | 32的倍数 |
p p p,精度 | 11 | 24 | 53 | 113 | k − r o u n d ( 4 × l o g 2 ( k ) ) + 13 k-round(4\times log_2(k))+13 k−round(4×log2(k))+13 |
e m a x emax emax,指数 e e e的最大值 | 15 | 127 | 1023 | 16383 | 2 ( k − p − 1 ) − 1 2^{(k-p-1)}-1 2(k−p−1)−1 |
– | – | – | – | – | – |
b i a s bias bias, E − e E-e E−e | 15 | 127 | 1023 | 16383 | e m a x emax emax |
符号位 | 1 | 1 | 1 | 1 | 1 |
w w w,指数位的宽度 | 5 | 8 | 11 | 15 | r o u n d ( 4 × l o g 2 ( k ) ) − 13 round(4\times log_2(k))-13 round(4×log2(k))−13 |
t t t,尾部有效位的宽度 | 10 | 23 | 52 | 112 | k − w − 1 k-w-1 k−w−1 |
k k k,数据宽度 | 16 | 32 | 64 | 128 | 1 + w + t 1+w+t 1+w+t |
这里 r o u n d round round表示四舍五入
指数项 E E E 具有关键作用(决定了浮点数的性质,以及计算公式)
性质:
(1) 当 E ∈ [ 1 , 2 w − 2 ] E\in [1,2^w-2] E∈[1,2w−2] 时,用于编码规范数(normal numbers)
(2) 当 E = 0 E=0 E=0 时,用于编码 ± 0 \pm0 ±0 和次规范数(subnormal numbers)
(3) 当 E = 2 w − 1 E = 2^w-1 E=2w−1 时,用于编码 ± ∞ \pm\infty ±∞ 和 NaNs
计算公式:
( r r r 是浮点数据的表示形式 , v v v 是浮点数据代表的值):
(a) 如果 E = 2 w − 1 E=2^w-1 E=2w−1,并且 T ≠ 0 T\neq0 T=0
则 r r r 就是 qNaN 或者 sNaN, v v v 就是 NaN(无论符号位)
(b) 如果 E = 2 w − 1 E=2^w-1 E=2w−1,并且 T = 0 T=0 T=0
则 r r r 和 v v v 都是 ( − 1 ) S × ( + ∞ ) \large(-1)^S\times(+\infty) (−1)S×(+∞)
(c) 如果 1 ⩽ E ⩽ 2 w − 2 1\leqslant E \leqslant2^w-2 1⩽E⩽2w−2 (这种情况居多)
则 r r r 就是 ( S , ( E − b i a s ) , ( 1 + 2 1 − p × T ) ) \large(S, (E-bias),(1+2^{1-p}\times T)) (S,(E−bias),(1+21−p×T)), v = ( − 1 ) S × 2 E − b i a s × ( 1 + 2 1 − p × T ) \large v=(-1)^S\times 2^{E-bias}\times(1+2^{1-p}\times T) v=(−1)S×2E−bias×(1+21−p×T)
(d) 如果 E = 0 E=0 E=0,并且 T ≠ 0 T\neq0 T=0
则 r r r 就是 ( S , e m i n , ( 0 + 2 1 − p × T ) ) \large(S, emin,(0+2^{1-p}\times T)) (S,emin,(0+21−p×T)), v = ( − 1 ) S × 2 e m i n × ( 0 + 2 1 − p × T ) \large v=(-1)^S\times 2^{emin}\times(0+2^{1-p}\times T) v=(−1)S×2emin×(0+21−p×T)
(e) 如果 E = 0 E=0 E=0,并且 T = 0 T=0 T=0
则 r r r 就是 ( S , e m i n , 0 ) \large(S,emin,0) (S,emin,0), v = ( − 1 ) S × ( + 0 ) \large v=(-1)^S\times (+0) v=(−1)S×(+0)
注意, 当 k k k是64或以上(32的倍数)时,各参数满足下列公式:
k = 1 + w + t = w + p = 32 × c e i l i n g ( ( p + r o u n d ( 4 × l o g 2 ( p + r o u n d ( 4 × l o g 2 ( 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) k=1+w+t=w+p=32×ceiling((p+round(4×log2(p+round(4×log2(p))−13))−13)/32)
w = k − t − 1 = k − p = r o u n d ( 4 × l o g 2 ( k ) ) − 13 w=k-t-1=k-p=round(4\times log_2(k))-13 w=k−t−1=k−p=round(4×log2(k))−13
t = k − w − 1 = p − 1 = k − r o u n d ( 4 × l o g 2 ( k ) ) + 12 t=k-w-1=p-1=k-round(4\times log_2(k))+12 t=k−w−1=p−1=k−round(4×log2(k))+12
p = k − w = t + 1 = k − r o u n d ( 4 × l o g 2 ( k ) ) + 13 p=k-w=t+1=k-round(4\times log_2(k))+13 p=k−w=t+1=k−round(4×log2(k))+13
e m a x = b i a s = 2 ( w − 1 ) − 1 emax=bias=2^{(w-1)}-1 emax=bias=2(w−1)−1
e m i n = 1 − e m a x = 2 − 2 ( w − 1 ) emin=1-emax=2-2^{(w-1)} emin=1−emax=2−2(w−1)
十进制转换格式编码
有空再说
扩展的和可扩展的精度
有空再说
有几个格式转换的网站可以参考
(1): https://www.h-schmidt.net/FloatConverter/IEEE754.html
(2): http://www.styb.cn/cms/ieee_754.php
(3): http://weitz.de/ieee/
假设内存中存了一个32位浮点数,十六进制:0x,二进制:0000000000000
图示如下:
根据上面的表1.3
可得32位二进制浮点数的参数:
p = 24 p=24 p=24, b i a s = 127 bias=127 bias=127, w = 8 w=8 w=8, t = 23 t=23 t=23
这里 E E E是二进制的,即十进制的128,满足 1 ⩽ E ⩽ 2 w − 2 1\leqslant E \leqslant2^w-2 1⩽E⩽2w−2,可以套公式
(c)
: v = ( − 1 ) S × 2 E − b i a s × ( 1 + 2 1 − p × T ) \large v=(-1)^S\times 2^{E-bias}\times(1+2^{1-p}\times T) v=(−1)S×2E−bias×(1+21−p×T)
即 v = ( − 1 ) 0 × 2 128 − 127 × ( 1 + 2 1 − 24 × 000000000000 ) \large v=(-1)^0\times 2^{128-127}\times(1+2^{1-24}\times 000000000000) v=(−1)0×2128−127×(1+21−24×11010000000000000000000)
由于这里是二进制,乘以 2 n 2^n 2n就是小数点向右移动 n n n个位,若 n n n是负数则向左移动 n n n个位。
于是 v = 1 × 2 × ( 1 + 0.101 ) = 1 × 2 × ( 1.1101 ) = 11.101 \large v=1 \times 2 \times(1+0.101)=1 \times 2 \times(1.1101)=11.101 v=1×2×(1+0.101)=1×2×(1.1101)=11.101
再转为十进制: v = 1 ⋅ 2 1 + 1 ⋅ 2 0 + 1 ⋅ 2 − 1 + 0 ⋅ 2 − 2 + 1 ⋅ 2 − 3 = 3.625 \large v=1\cdot2^1+1\cdot2^0+1\cdot2^{-1}+0\cdot2^{-2}+1\cdot2^{-3}=3.625 v=1⋅21+1⋅20+1⋅2−1+0⋅2−2+1⋅2−3=3.625
结果是3.625
现在有一个十进制的小数13.78125
,要转成32位的二进制浮点数编码。
先看整数部分:
13 ÷ 2 = 6 13\div 2 = 6 13÷2=6 余 1
6 ÷ 2 = 3 6\div 2 = 3 6÷2=3 余 0
3 ÷ 2 = 1 3\div 2 = 1 3÷2=1 余 1
1 ÷ 2 = 0 1\div 2 = 0 1÷2=0 余 1
因此整数部分二进制为1101
再看小数部分:
0.78125 × 2 = 1.5625 0.78125 \times 2 = 1.5625 0.78125×2=1.5625,整数部分1
0.5625 × 2 = 1.125 0.5625 \times 2 = 1.125 0.5625×2=1.125,整数部分1
0.125 × 2 = 0.25 0.125 \times 2 = 0.25 0.125×2=0.25,整数部分0
0.25 × 2 = 0.5 0.25 \times 2 = 0.5 0.25×2=0.5,整数部分0
0.5 × 2 = 1 0.5 \times 2 = 1 0.5×2=1,整数部分1
因此小数部分为11001
,所以13.78125
的二进制表示是1101.11001
再看格式转换:
根据浮点数表示形式(1)
: ( − 1 ) s × b e × m (-1)^{s} \times b^e \times m (−1)s×be×m,把二进制小数用该形式表示:
1101.11001 = ( − 1 ) 0 × 2 3 × 1. 1101.11001 = (-1)^0\times2^3\times1. 1101.11001=(−1)0×23×1.10111001
得: S = S= S= 0
, e = 3 e=3 e=3, m = 1. m=1. m=1.10111001
查表1.3
得32位的浮点数的参数: p = 24 p=24 p=24, b i a s = 127 bias=127 bias=127, w = 8 w=8 w=8, p = 24 p=24 p=24
由 b i a s = E − e bias=E-e bias=E−e 得: E = b i a s + e = 127 + 3 = 130 E = bias+e=127+3=130 E=bias+e=127+3=130, E E E 的二进制值为:
由于 E E E 符合 1 ⩽ E ⩽ 2 w − 2 1\leqslant E \leqslant2^w-2 1⩽E⩽2w−2 ,可以套公式(c)
:
1101.11001 = ( − 1 ) S × 2 E − b i a s × ( 1 + 2 1 − p × T ) 1101.11001=(-1)^S\times 2^{E-bias}\times(1+2^{1-p}\times T) 1101.11001=(−1)S×2E−bias×(1+21−p×T)
= ( − 1 ) 0 × 2 130 − 127 × ( 1 + 2 1 − 24 × 000000000000 ) =(-1)^0\times 2^{130-127}\times(1+2^{1-24}\times 000000000000) =(−1)0×2130−127×(1+21−24×10111001000000000000000)
所以 T = T= T= 000000000000
S S S、 E E E、 T T T 都算出来了,由图1.1
得32位二进制结果:0000000000000