浮点数原理与精度损失问题

2020-10-22  本文已影响0人  TOMOCAT

写在前面

碰巧最近定义接口的时候碰到了浮点数精度的问题,稍微整理了浮点数的一些知识点:

小数的二进制表示

浮点数的表示借鉴了科学计数法,比如在十进制中311.56可以表示成3.1156 * 10^2。类似地,浮点型数据的二进制存储结构也可以被划分成:符号位 + 指数位 + 尾数位。按照国际标准IEEE 754,任意一个二进制浮点数可以表示成:
V = (-1)^s \times M \times 2^E
其中:

指数部分决定了数的大小范围,有效数字部分决定了数的精度。

举两个简单的例子:

十进制 二进制 二进制科学计数法 S E M
3.0 11.0 1.1 x 2^1 0 1 1.1
-5.0 -101.0 -1.01 x 2^2 1 2 1.01

浮点数在计算机底层的存储机制

double类型和float类型(可能还有long double类型)在计算机的底层存储结构都是一致的,唯一的不同在于float是32位而double是64位的。

无论什么数据,在计算机内存中都是以01存储的,浮点数也不例外。

0. 定点数

计算机中小数的表示按照小数点的位置是否固定可以分为浮点数和定点数。为了方便和float32浮点数做对比,我们构造一个32位精度的定点数,其中小数点固定在23bit处:

定点数的底层表示

从定点数的存储上看,它表示的数值范围有限(以小数点在23bit为例,整数部分仅有8位,则整数部分取值范围是0~255),但好在处理定点数计算的硬件比较简单。

1. IEEE 754x浮点数

以32位浮点数为例,最高一位是符号位s,接着的8位是指数位E,最后的23位是有效数字M。double64最高一位是符号位,有11个指数位和52个有效数字位。下图展示了float32类型的底层表示:


float的底层表示

其中IEEE 754的规定为:

image.png

2. 具体例子

以78.375为例,它的整数和小数部分可以表示为:
(78)_{10} = (1001110)_{2} \\ (0.375)_{10} = \frac{3}{8} = \frac{1}{4} + \frac{1}{8} = 2^{-2} + 2^{-3} = (0.01)_2 + (0.001)_2 = (0.011)_2
因此二进制的科学计数法为:
(78.375)_{10} = (1001110.011)_2 = 1.001110011 \times 2^6
一般而言转换过程包括如下几步:

按照前面IEEE 754的要求,它的底层存储为:

image.png

3. 精度损失

十进制中的0.5(代表分数1/2)表示二进制中的0.1(等同于分数1/2),我们可以把十进制中的小数部分乘以2作为二进制的一位,然后继续取小数部分乘以2作为下一位,直到不存在小数为止。以0.2这个无法精确表示成二进制的浮点数为例:
0.2 \times 2 = 0.4 \rightarrow 0 \\ 0.4 \times 2 = 0.8 \rightarrow 0 \\ 0.8 \times 2 = 1.6 \rightarrow 1 \\ 0.6 \times 2 = 1.2 \rightarrow 1 \\ 0.2 \times 2 = 0.4 \rightarrow 0 \\ ...... \\ (0.2)_{10} = (0.00110...)_{2}
因此十进制下的0.2无法被精确表示成二进制小数,这也是为什么十进制小数转换成二进制小数时会出现精度损失的情况。

浮点型表示精度和范围

以float为例,能表示的最大二进制数据为+1.11111111111111111111111\times 2^{127}(小数点后为23个1),而二进制下1.111111... \approx 2,因此能表示的最大十进制数据是:
(+1.11111111111111111111111 \times 2^{127})_2 \approx (2^{128})_2 \approx (3.4 \times 10^{38})_{10}

从二进制小数的科学计数法表示上看,可以知道float的精度为\frac{1}{2}^{23},double的精度为\frac{1}{2}^{52}

Reference

[1] https://q.115.com/182920/T1268124.html

[2] https://blog.csdn.net/u014470361/article/details/79820892

[3] https://www.cnblogs.com/wangsiting1997/p/10677805.html

[4] https://blog.csdn.net/u014470361/article/details/79820892

[5] https://www.cnblogs.com/yiyide266/p/7987037.html

上一篇下一篇

猜你喜欢

热点阅读