最近调了几个问题,都和double的运算精度有关。
double在运算的时候,是不准的,所以一般用BigDecimal来代替double。将double转换为BigDecimal通常有两种做法,也就是BigDecimal构造方法中的两个,一个是BigDecimal(String val),另一个是BigDecimal
(double val)。这里推荐使用第一个,即参数是String的那个构造方法。在API文档中也说了,参数为double的构造方法有一定的不可预知性,而参数为String是完全可预知的。
使用BigDecimal的时候,尤其是除法的时候,通常是要设置精度的,否则,诸如1/3这样无限小数时,会报异常“java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.”在设置精度的同时,是要选择舍入的方式的。比较熟悉的一种就是四舍五入,但这种舍入方式其实也不够精确。有一种比四舍五入更精确的一种舍入方法叫做“四舍六入五成双”。四舍六入好理解,这里说一下5的处理。如果5的后面没有除0以外的数字,那么5前面是奇数,则进1,是偶数,则舍去。如果5的后面有除0以外的数字,那么不管5前面的数是奇数或者偶数,都要进1。具体的讲解可以看一下百度百科上的解释(http://baike.baidu.com/view/1245064.htm)。四舍六入五成双的舍入方式在BigDecimal对应的是BigDecimal.ROUND_HALF_EVEN这个字段。
尽管如此,误差始终是存在的,有的时候还是要自己想一些方法来处理一下误差的。