引言
在计算机科学领域中,浮点数是一种用于表示近似实数的数据类型,广泛应用于科学计算、工程设计、金融建模等领域。在日常编程中,我们经常会遇到浮点数的计算和处理,然而,由于浮点数在计算机中的存储和表示方式,以及二进制与十进制之间的转换问题,可能会导致计算精度丢失,从而影响计算结果的准确性。
本文将介绍浮点数的基本概念,包括单精度和双精度浮点数的区别,以及计算精度丢失问题的原因和解决方法。通过深入理解浮点数的内部表示和计算机中的运算规则,我们可以更好地处理浮点数计算中的精度问题,提高程序的稳定性和准确性。
浮点类型
浮点类型,分为单精度和双精度,他们是用于表示浮点数的两种不同的数据类型,它们在计算机中存储和处理浮点数时具有不同的精度和范围。
-
单精度浮点数(float):
- 使用 32 位来表示一个单精度浮点数,其中包括一个符号位、8 位指数和 23 位尾数。
- 可以表示的数值范围约为 ±3.40282347 × 10^38,且具有大约 7 位有效数字。
- 适用于较小范围的浮点数计算,但精度较低。
-
双精度浮点数(double):
- 使用 64 位来表示一个双精度浮点数,其中包括一个符号位、11 位指数和 52 位尾数。
- 可以表示的数值范围约为 ±1.79769313486231570 × 10^308,且具有大约 15-16 位有效数字。
- 具有更高的精度和更广泛的数值范围,适用于大多数数值计算应用。
双精度浮点数(double)比单精度浮点数(float)在存储范围和精度上都更优,但也需要更多的存储空间和处理器资源。因此,通常在不受存储和性能限制的情况下,双精度浮点数更常用。
说明
一个浮点数 (Value) 的表示其实可以这样表示:
也就是 浮点数的实际值
,等于符号位(sign bit)乘以指数偏移值(exponent bias)再乘以分数值(fraction)。
浮点数标准
java中浮点数采用的IEEE754标准,该标准的全称为IEEE二进制浮点数算术标准。
存储格式:符号位+指数位偏移+尾数位
符号位S_指数位E_尾数位M
例如,一个float类型的数据占用4个字节共32位,其各个组成部分为:
- 符号位(S):最高位(31位)为符号位,表示整个浮点数的正负,0为正,1为负
- 指数位(E):23-30位共8位为指数位,这里指数的
底数规定为2
。并且指数位是以补码的形式来划分的(最高位为指数位的符号位,0为正,1为负)。另外,标准中还规定了,当指数位8位全0或全1的时候,浮点数为非正规形式,所以指数位真正范围为:-126~127
。 - 尾数位(M):0-22位共23位为尾数位,表示小数部分的尾数,即形式为1.M或0.M,至于什么时候是 1 什么时候是 0,则由指数和尾数共同决定。小数部分最高有效位是1的数被称为正规(规格化)形式。小数部分最高有效位是0的数被称为非正规(非规格化)形式,其他情况是特殊值。
IEEE 754常用的两种表示浮点数值的方式:单精确度(float 32位)、双精确度(double 64位)
- 规约形式的浮点数
1.M
如果浮点数中指数部分的编码值在0 \< exponent \< 2e-2之间
,且尾数部分最高有效位(即整数字)是1,那么这个浮点数将被称为规约形式的浮点数。“规约”是指用唯一确定的浮点形式去表示一个值。
由于这种表示下的尾数有一位隐含的二进制有效数字,为了与二进制科学计数法的尾数相区别,IEEE754称之为有效数(significant)。 - 非规约形式的浮点数
0.M
如果浮点数的指数部分的编码值是0&