浮点数

2017-10-27  本文已影响23人  SScience

1,浮点数基本知识

Java 语言支持两种基本的浮点类型: float 和 double ,以及与它们对应的包装类 Float 和 Double 。它们都依据 IEEE 754 标准,该标准定义了32 位单精度和 64 位双精度两种浮点二进制小数标准。

IEEE 754 用科学记数法以底数为 2 的小数来表示浮点数。

IEEE 浮点值的格式如图 1 所示:

图 1. IEEE 754 浮点数的格式

2,浮点数比较

在java中浮点型默认是double的,浮点数都要在计算机里转换进行二进制存储,这就涉及到数据精度。
例如,十进制小数0.9表示成二进制数为:1100100100100......后面部分将无限循环下去,很显然,小数的二进制表示有时是不可能精确的。比如double类型表示小数部分只有52位,当向后计算52位后基数还不为0,那后面的部分只能通过四舍五入得到一个近似值,此时就造成精度丢失。
所以,当浮点数进行比较时,由于浮点数的二进制表示本身就不准确,比较大小时就会出现错误。例如float f1 = 20014999f == float f2 = 20015000f。

因此,有个原则:

3,BigDecimal

要想获得理想的结果,应该使用BigDecimal来获得更精确的计算。
在《Effective Java》这本书中也提到这个原则,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal

BigDecimal够造方法的参数类型有4种,其中的两个用BigInteger构造,另一个是用double构造,还有一个使用String构造。应该避免使用double构造BigDecimal,因为:有些数字用double根本无法精确表示,传给BigDecimal构造方法时就已经不精确了。
比如,new BigDecimal(0.1)得到的值是0.1000000000000000055511151231257827021181583404541015625。使用new BigDecimal("0.1")得到的值是0.1。因此,如果需要精确计算,用String构造BigDecimal,避免用double构造。

BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,由于创建对象会引起开销,因此它们不适合于大量的数学运算,所以a.add(b);虽然做了加法操作,但是a并没有保存加操作后的值,正确的用法应该是a=a.add(b)。

4,小数点位数保留

参考:
https://www.ibm.com/developerworks/cn/java/j-jtp0114/index.html
http://blog.csdn.net/ccecwg/article/details/22286873
http://www.cnblogs.com/chenfei0801/p/3672177.html
http://www.ituring.com.cn/article/216160
http://swiftlet.net/archives/798
http://www.jianshu.com/p/00fff555986b

上一篇 下一篇

猜你喜欢

热点阅读