1.2.2 浮点类型
浮点类型表示有小数部分的数值。Java中的两种浮点类型如表1-2所示。
表1-2 浮点类型
很多年前,当内存还是一种稀缺资源时,4 字节的浮点数是最常用的。但现在 7 位有效数字已经不太适用了,因此“双精度”数是系统的默认值。只有当需要存储大量的浮点数时,使用float类型才有意义。
float类型的数值有一个后缀F(例如,3.14F);没有后缀F的浮点数(例如,3.14)是double类型的。当然,你可以选择使用后缀D(例如,3.14D)来表示double类型的数值。
注意:你可以用十六进制来表示浮点数。例如,0.0009765625 = 2−10,也可以写成0x1.0p-10。在十六进制符号中,你需要使用p而不是e来表示指数。(因为e是一个十六进制数字。)请注意,即使数字是十六进制的,但指数(即2的幂)也需要使用十进制。
Java中有一些特殊的浮点值:Double.POSITIVE_INFINITY表示∞;Double.NEGATIVE_INFINIY表示−∞;Double.NaN表示“非数值”。例如,算式1.0/0.0的结果是正无穷大。算式0.0/0.0或负数的平方根会生成NaN。
警告:所有“非数值”都会被认为是各不相同的。因此,你不能使用条件测试语句if (x == Double.NaN) 来检查 x 是否为 NaN。而是应该使用 if (Double.isNaN(x))来判断。此外,也应当使用Double.isInfinite来测试±∞,用Double.isFinite来检查一个浮点数既不是无穷也不是NaN。
浮点数并不适用于金融计算的场景,因为它在计算中发生的一些舍入误差对金融领域来讲可能是无法容忍的。例如,System.out.println(2.0 - 1.7)将会打印出0.30000000000000004,而不是你所期望的0.3。这种舍入误差是由浮点数在二进制系统中的表示规则造成的。此外,小数3/10也没有精确的二进制表示,就像十进制系统中1/3没有精确的表示一样。如果你需要任意精度且没有舍入误差的数值计算,可以使用1.4.6小节中介绍的BigDecimal类。