Double类是基本类型double的包装类,其中的主要属性和方法与Float类相似。在本文中就不列出了,大家可以看下一起学JDK源码 -- Float类
基础知识:
1.浮点数的表示:
浮点数由三部分组成,符号位s、指数e和尾数f。
对于float表示如下
0 00000000 00000000000000000000000
sign(1bit) exponent(8bit) fraction(23bit) 共32bit
对于求值我们是有一个公式对应的,某个浮点数的值为:
(−1)^s ∗ (1.f) ∗ 2^(e−127)
可以看到32位的最高位为符号标识符,1表示负数,0表示正数。指数部分为8位,其实可以是0到255,但是为了可正可负,这里需要减去127后才是真正的指数,而底数固定为2。剩下的23位表示尾数,但默认前面都会加上1.。所以通过上面就可以将一个浮点数表示出来了。
我们举个例子来看,二进制的“01000001001101100000000000000000”表示的浮点数是啥?
符号位为0,表示正数。
指数为“10000010”,减去127后为3。
尾数对应的值为“1.011011”。
于是最终得到浮点数为“1011.011”,转成十进制为“11.375”。
2.精度丢失:
对float或double 的使用不当,可能会出现精度丢失的问题。浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。往往产生误差不是 因为数的大小,而是因为数的精度。因此,产生的结果接近但不等于想要的结果。尤其在使用 float 和 double 作精确运 算的时候要特别小心。如:
System.out.println(0.1d + 0.2d);这个输出的结果不是我们想要的0.3而是0.30000000000000004。这就是java中的精度丢失。可以使用如下方式解决:
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal b2 = new BigDecimal("0.2");
System.out.println(b1.add(b2));
所以大家在遇到金钱等对精度要求较高的业务时最好不要使用浮点类型的数。可以考虑使用BigDecimal。或是把单位转换成分,这样处理的数字都是整数,最后再化成小数。这样就不会出现精度丢失的问题了。