> For the complete documentation index, see [llms.txt](https://deployment.gitbook.io/love/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://deployment.gitbook.io/love/whitepaper/quantization_and_pruning/ieee754.md).

# IEEE754标准

source from https\://www\.hello-algo.com/🚀

## 浮点数编码

记一个 32 比特长度的二进制数为：

$$
b\_{31} b\_{30} b\_{29} \ldots b\_2 b\_1 b\_0
$$

根据 IEEE 754 标准，32-bit 长度的 `float` 由以下三个部分构成。

* 符号位 $$\mathrm{S}$$ ：占 1 位 ，对应 $$b\_{31}$$。
* 指数位 $$\mathrm{E}$$ ：占 8 位 ，对应 $$b\_{30} b\_{29} \ldots b\_{23}$$。
* 分数位 $$\mathrm{N}$$ ：占 23 位 ，对应 $$b\_{22} b\_{21} \ldots b\_0$$。

二进制数 `float` 对应值的计算方法为：

$$
\text {val} = (-1)^{b\_{31}} \times 2^{\left(b\_{30} b\_{29} \ldots b\_{23}\right)*2-127} \times\left(1 . b*{22} b\_{21} \ldots b\_0\right)\_2
$$

转化到十进制下的计算公式为：

$$
\text {val}=(-1)^{\mathrm{S}} \times 2^{\mathrm{E} -127} \times (1 + \mathrm{N})
$$

其中各项的取值范围为：

$$
\begin{aligned} \mathrm{S} \in & { 0, 1}, \quad \mathrm{E} \in { 1, 2, \dots, 254 } \newline (1 + \mathrm{N}) = & (1 + \sum\_{i=1}^{23} b\_{23-i} 2^{-i}) \subset \[1, 2 - 2^{-23}] \end{aligned}
$$

<figure><img src="https://3100114358-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FyhXXzVY3gexs8StunmSt%2Fuploads%2FCATz42xIfqrjQxQC9eJX%2F%E5%9B%BE%E7%89%87.png?alt=media&amp;token=bd905e53-c0e1-439e-a611-7ab0e21cc2a1" alt="" width="563"><figcaption></figcaption></figure>

观察上图，给定一个示例数据 $$\mathrm{S} = 0$$ ， $$\mathrm{E} = 124$$ ，$$\mathrm{N} = 2^{-2} + 2^{-3} = 0.375$$ ，则有：

$$
\text { val } = (-1)^0 \times 2^{124 - 127} \times (1 + 0.375) = 0.171875
$$

现在我们可以回答最初的问题：**`float` 的表示方式包含指数位，导致其取值范围远大于 `int`** 。根据以上计算，`float` 可表示的最大正数为 $$2^{254 - 127} \times (2 - 2^{-23}) \approx 3.4 \times 10^{38}$$ ，($$2^{e-1}-1=127$$)切换符号位便可得到最小负数。

<mark style="color:red;">**尽管浮点数**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**`float`**</mark><mark style="color:red;">**&#x20;**</mark><mark style="color:red;">**扩展了取值范围，但其副作用是牺牲了精度**</mark><mark style="color:red;">。整数类型</mark> <mark style="color:red;"></mark><mark style="color:red;">`int`</mark> <mark style="color:red;"></mark><mark style="color:red;">将全部 32 比特用于表示数字，数字是均匀分布的；而由于指数位的存在，浮点数</mark> <mark style="color:red;"></mark><mark style="color:red;">`float`</mark> <mark style="color:red;"></mark><mark style="color:red;">的数值越大，相邻两个数字之间的差值就会趋向越大。</mark>

如下表所示，指数位 $$\mathrm{E} = 0$$ 和 $$\mathrm{E} = 255$$ 具有特殊含义，**用于表示零、无穷大、**$$\mathrm{NaN}$$ **等**。

| 指数位 E                | 分数位 N = 0      | 分数位 N != 0       | 计算公式                                                                     |
| -------------------- | -------------- | ---------------- | ------------------------------------------------------------------------ |
| $$0$$                | $$\pm 0$$      | 次正规数             | $$(-1)^{\mathrm{S}} \times 2^{-126} \times (0.\mathrm{N})$$              |
| $$1, 2, \dots, 254$$ | 正规数            | 正规数              | $$(-1)^{\mathrm{S}} \times 2^{(\mathrm{E} -127)} \times (1.\mathrm{N})$$ |
| $$255$$              | $$\pm \infty$$ | $$\mathrm{NaN}$$ |                                                                          |

值得说明的是，次正规数显著提升了浮点数的精度。最小正正规数为 $$2^{-126}$$ ，最小正次正规数为 $$2^{-126} \times 2^{-23}$$。双精度 `double` 也采用类似于 `float` 的表示方法，在此不做赘述。
