Go语言底层原理剖析
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.7 浮点数精度

精度是一个复杂的概念,大部分人对精度有一些误解。当在互联网上搜索单精度浮点数的精度到底为多少时,会看到许多不同的答案:6位、7位、8位。然而实际情况是浮点数的精度是不固定的,并且,一般在谈论浮点数的精度时都有一个默认的前提,即讨论的是二进制浮点数的十进制精度。

在一个范围内,将d位十进制数(按照科学计数法表达)转换为二进制数,再将二进制数转换为d位十进制数,如果数据转换不发生损失,则意味着在此范围内有d位精度。

精度存在的原因在于,数据在进制之间相互转换时,不是精准匹配的,而是匹配到一个最接近的值。如图2-2(a)所示,十进制数转换为二进制数,二进制数又转换为十进制数,如果能够还原为最初的值,那么转换精度是无损的,说明在当前范围内浮点数是有d位精度的。反之,如图2-2(b)所示,d位十进制数转换为二进制数,二进制数又转换为d位十进制数,得到的并不是原来的值,那么说明在该范围内浮点数没有d位精度。2的幂与10的幂不是一一对应的,导致在不同的范围内可能有不同的精度。

图2-2 精度存在的原因

理论表明,单精度浮点数float32的精度为6~8位,双精度浮点数float64的精度为15~17位。图2-3所示为单精度浮点数在10进制不同范围内的精度。

当十进制数的小数部分在6位之内时,单精度浮点数能够精确表示其值;当十进制数的小数部分在7~8位时,单精度浮点数能否精准表示其值取决于其所在的范围;而当十进制数的小数部分超过8位时,单精度浮点数将不能精准表达其值。

图2-3 单精度浮点数在10进制不同范围内的精度[1]