起因是看了一个视频关于由远视距导致的Z-fighting及其解决方案,于是想着具体推导一下。
暂时不考虑符号位(因为无关),在 IEEE 754 标准中,一个规格化浮点数表示为:
$$ \left(1 + \text{Mantissa}\right) \times 2^E $$
其中的Mantissa(尾数)部分可以理解为用一个23位(单精度浮点数的尾数位数是23位)的二进制均匀映射到一个$[0, 1)$的数值区间,来表示尾数部分,即下面的这个公式表达一个浮点数的实际数值(先不考虑$E$的偏移,因为无关):
$$ \text{Value} = \left(1 + \frac{m}{2^{23}}\right) \times 2^E $$
然而这个$[0, 1)$区间还被乘以了指数部分$2^E$,进行了加权,所以实际上尾数部分的23位二进制实际映射的数值区间又会随着$E$而改变。此时可以看出当$E$越大,这23位二进制所映射的数值区间会变得越大,这23位二进制表示的尾数精度会越差。
感性理解后,我们可以具体数值推导一下。为了量化精度,我们可以计算在不同指数$E$下,相邻两个浮点数之间的差值是多少,差值越小,说明精度越好。
相邻两个浮点数,即紧挨着尾数为$m$的浮点数的下一个浮点数的尾数为$m+1$,同时他们指数$E$相同。那么他们的差值$\text{Step Size}$可得:
$$ \text{Value} = \left(1 + \frac{m}{2^{23}}\right) \times 2^E = 2^E + m \times 2^{E - 23} $$
$$ \text{Step Size} = \left( 2^E + (m + 1) \times 2^{E - 23} \right) - \left( 2^E + m \times 2^{E - 23} \right) = 2^{E - 23} $$
可见当$E$变大时,相邻浮点数的差值会变大,所以精度会降低。所以$E$越小,越接近0的浮点数,其精度越高,证毕。