浮点数

小数

小数的表示

对于任意进制 b (b > 1),分数 $\frac{p}{q}$ 可以表示如下(任何分数都可以转换为一个对应的小数)

$\frac{p}{q}$ 对应的小数形式为 ${y_n} \dots {y_2}{y_1}.{x_1}{x_2} \dots {x_n}$

各位数字的权重分布如下: $\underset{b^n}{y_n} \dots \underset{b^2}{y_2}\underset{b^1}{y_1}.\underset{b^{-1}}{x_1}\underset{b^{-2}}{x_2} \dots \underset{b^{-n}}{x_n}$

所以分数 $ \frac{p}{q} $ 值的计算公式为: $ \frac{p}{q}=y_{n}b^{n} + \dots + y_2b^{2} + y_1b^{1} + y_{0}b^0 + x_{1}b^{-1} + x_{2}b^{-2} + \ldots + x_{n}b^{-n} $

$x_n$ $y_n$ 为权位系数,其中 $ 0 \leq x_{n} < b$,$ 0 \leq y_{n} < b$ 并且 $ x_{n} \neq 0 $, $y_{n} \neq 0 $, $n\in\mathbb{N}$,$p\in\mathbb{N}$,$q\in\mathbb{N}$。

十进制小数示例:

$ 101.125_{10} = 1\times10^2 + 0\times10^1 + 1\times10^0 + 1\times10^{-1} + 2\times10^{-2} + 3\times10^{-3} $

二进制小数示例:

$11.11_2 = 1\times2^1 + 1\times2^0 + 1\times2^{-1} + 1\times2^{-2} = 3.75_{10}$

小数的进制转换

以 $100.375_{10}$ 为例:

整数部分:

$ 100_{10}=y_{n}2^{n} + \dots + y_22^{2} + y_12^{1} + y_02^0 $ $ 100_{10}=2(y_{n}2^{n-1} + \dots + y_22^{1} + y_1) + y_0 $ $ 100_{10}=2(2(y_{n}2^{n-2} + \dots + y_2) + y_1) + y_0 $ $\dots$

$100_{10} = 2\times50 + 0$ $100_{10} = 2\times(2\times25 + 0) + 0$ $100_{10} = 2\times(2\times(2\times12 + 1) + 0) + 0$ $100_{10} = 2\times(2\times(2\times(2\times6 + 0) + 1) + 0) + 0$ $100_{10} = 2\times(2\times(2\times(2\times(2\times3 + 0) + 0) + 1) + 0) + 0$ $100_{10} = 2\times(2\times(2\times(2\times(2\times(2\times1 + 1) + 0) + 0) + 1) + 0) + 0$

所以 $100_{10} = 1100100_2$

小数部分:

$ 0.375_{10} = 2^{-1}\times0.75 + 0$ $ 0.375_{10} = 2^{-1}\times(2^{-1}\times(0.5 + 1)) + 0 $ $ 0.375_{10} = 2^{-1}\times(2^{-1}\times(2^{-1}\times(1) + 1)) + 0 $

所以 $ 0.375_{10} = 0.011_{2} $

将任意分数 $\frac{p}{q}$ 转换为 b 进制(b > 1)表示时,如果分数 $\frac{p \times b}{q}$ 的分子 $p \times b$ 和 分母q不存在质因数,$\frac{p}{q}$ 对应的小数就是无限循环小数。

比如$\frac{1}{3}$无法用10进制精确表示为小数形式: $\frac{1}{10} = 0.33333\dots$,$\frac{1}{10}$无法用2进制精确表示为小数形式: $\frac{1}{10} = 0.000110011\dots$

专业解释: Expansion of Integers in an Integer Base

浅显易懂版: The simple math behind decimal-binary conversion algorithms

定点数(fixed point)

有符号数用 $Q_{m.n}$ (m整数部分位数,m没可选值,n小数部分位数),如$Q_{1.15}$,整数部分1位,小数部分15位,加上符号位共16位。

无符号数用 $UQ_{m.n}$ (m整数部分位数,m没可选值,n小数部分位数),如$Q_{16.16}$。

$ \underset{sign}{0}\underbrace{000000000000000}_{integer}\underset{dot}{.}\underbrace{0000000000000000}_{fraction} $

小数点只是逻辑上的,并不会占位存储。整数部分决定了数值范围,小数部分决定了数值精度。

优点

  • 格式简单,CPU实现也就简单所以省钱又节能

缺点

  • 运算结果存在精度丢失和容易溢出问题(最典型的就是二进制乘法运算)
  • 整数和小数位固定,精度和数值范围不好平衡

通常嵌入式系统使用定点小数 数字信号处理(DSP)

浮点数(float point/exponential)

IEEE-754 二进制交换格式编码

使用科学计数法表示,由符号位(sign)、指数(exponent)以及小数(fraction)三部分组成。以64位双精度浮点数为例,符号位1位,指数位11位,小数位52位。

IEEE-754

指数位E占11位,可以表示[0, 2047]范围内的数,0 和 2047用做特殊用途,实际可用范围[1, 2046]。

当 $ E = 00000000000_2 $ 且 $ F = 0 $ 表示 $\pm0$

当 $ E = 00000000000_2 $ 且 $ F \neq 0 $ 表示非正常数字(Subnormal Number也叫Denormal Number),用于表示两个非常接近的数的差值。 详情参见Denormal number

当 $ E = 11111111111_2 $ 且 $ F = 0 $ 表示 $ \pm\infty $

当 $ E = 11111111111_2 $ 且 $ F = 1 $ 表示 NaN(qNaN和sNaN)

指数可以为正数和负数,取中间值1023为偏差值,小于1023的值减去1023得到负指数,大于1023的值减去1023得到正指数,所以指数实际取值范围为[-1022, 1023]。

对于所有正常数字,双精度浮点数描述为: $ (−1)^{sign} \times 1.f \times 2^{e−1023} $ // s代表符号位 e代表小数位 e代表指数位

对于正常数字,小数位隐含最高位为1,所以表示为1.f。$ f = f_1f_2f_3 \dots f_{52} = f_1\times2^{-1} + f_2\times2^{-2} + f_3\times2^{-3} \dots f_{52}\times2^{-52} $

通过指数部分可以控制小数点左右浮动。

实例:

$0\ 01111111111\ 00000000000000000000000000000000000000000000000000000_2 = 2^{1023 - 1023} \times (1 + 0) = 0\ 1 = 1$ $1\ 10000000000\ 0000000000000000000000000000000000000000000000000000_2 = -2^{1024 - 1023} \times (1 + 0) = 1\ 10_2 = -2$

$0\ 10000000001\ 1000000000000000000000000000000000000000000000000000_2 = 2^{1025 - 1023} \times (1 + 2^{-1}) = 0\ 110_2 = 6$ 指数为+2, 1.1小数点右移两位低位补0得到110。

$0\ 01111111101\ 1000000000000000000000000000000000000000000000000000_2 = 2^{1021-1023} \times (1 + 2^{-1}) = 0\ 0.011_2 = 0.375$ 指数为-2,1.1小数点左移2位得到0.011

64位浮点数能表示的最大的数为: $0\ 11111111110\ 1111111111111111111111111111111111111111111111111111_2 = 2^{2046 - 1023} \times (1 + (1 - 2^{-52})) \approx 1.7976931348623157 × 10^{308}$

64位浮点数能正常表示的最大整数为(小数部分点向右偏移52位): $0\ 10000110011‬\ 1111111111111111111111111111111111111111111111111111_2 = 2^{1075 - 1023} \times (1+(1 - 2^{-52})) = 2^{53} -1 = 9\ 007\ 199\ 254\ 740\ 991‬$

对于非正常数字(Subnormal Number),双精度浮点数描述为: $ (−1)^{sign} \times 0.f \times 2^{1−1023} $

对于非正常数字,小数位隐含最高位为0

运算

IEEE 754 Calculator

更多细节参见维基百科:

Double-precision floating-point format

IEEE-754 十进制格式

// TODO 补充

进制转换

对于任意进制 b (b > 1),自然数 a 可以表示如下

$ a=x_{0}b^0 + x_{1}b^1 + x_{2}b^{2} + \ldots + x_{n}b^{n} $

其中 $ 0 \leq x_{i}<b$ 并且 $x_{n} \neq 0 $

以十进制为例

$ 125 = 1\times10 ^2 + 2\times10 ^ 1 + 5\times10^0 $ $ 0.125 = 1\times10^{-1} + 2\times10^{-2} + 3\times10^{-3} $

以二进制为例

$ 125 = 1\times2^6 + 1\times2^5 + 1\times2^4 + 1\times2^3 + 0\times2^2 + 1\times2^1 + 1\times2^0$ $ 0.125 = 0\times2^{-1} + 0\times2^{-2} + 1\times2^{-3} $

对于任意进制 b (b > 1),分数(fraction) $\frac{p}{q}$ 可以表示如下(任何分数都可以转换为一个对应的小数)

$ \frac{p}{q}=x_{0}b^0 + x_{1}b^-1 + x_{2}b^{-2} + \ldots + x_{n}b^{-n} $

其中 $ 0 \leq x_{i}<b$ 并且 $x_{n} \neq 0 $。我们可以看出 $ x_{i} $ 就是权位的系数。

$ 0.125 = 0\times2^{-1} + 0\times2^{-2} + 1\times2^{-3} $

$ 0.125 = 2^{-1}(0 + 0\times2^{-1} + 1\times2^{-2}) $

$ 0.125 * 2 = 0 + 2^{-1}(0 + 1\times2^{-1}) $

$ 0.25 * 2 = 0 + 0 + 1\times2^{-1}$

$ 0.5 * 2 = 1 $

所以 0.125用二进制小数表示为$ 0.001_{2} $,再根据IEEE-754规则转换为64位双精度浮点数格式。0.001相当于小数部分向右偏移了3位,所以指数部分的取值为$ 1023 - 3 = 1020_{10} = 01111111100_{2} $,结果如下:

$0\ 01111111100\ 1000000000000000000000000000000000000000000000000000_2$

将任意分数 $\frac{p}{q}$ 转换为 b 进制(b > 1)表示时,如果分数 $\frac{p \times b}{q}$ 的分子 $p \times b$ 和 分母q不存在质因数,$\frac{p}{q}$ 对应的小数就是无限循环小数。

比如$\frac{1}{3}$无法用10进制精确表示为小数形式: $\frac{1}{10} = 0.33333\dots$,$\frac{1}{10}$无法用2进制精确表示为小数形式: $\frac{1}{10} = 0.000110011\dots$

专业解释: Expansion of Integers in an Integer Base

浅显易懂版: The simple math behind decimal-binary conversion algorithms

小数(Decimal)

参考资料