今天无意中看以前的东东,发现两个double类型的数直接相加时,得到的结果不对
import java.math.BigDecimal;
public class TestDouble {
public static void main(String[] args) {
double d1 = 0.01;
double d2 = 0.05;
String s1 = "8.0";
String s2 = "3.0";
System.out.println(d1+d2);//结果为0.060000000000000005,其中缘由还不明白,请大侠们多多指教
//需要转换成BigDecimal 类型可以得到正确结果
BigDecimal bd1 = new BigDecimal(d1+"");
BigDecimal bd2 = new BigDecimal(d2+"");
System.out.println(
bd1.add(bd2).doubleValue());//BigDecimal 类型加
System.out.println(bd1.subtract(bd2).doubleValue());//BigDecimal 类型减
BigDecimal bd3 = new BigDecimal(s1);
BigDecimal bd4 = new BigDecimal(s2);
System.out.println(
bd3.multiply(bd4).doubleValue());//BigDecimal 类型乘
System.out.println(
bd3.divide(bd4,6,BigDecimal.ROUND_HALF_UP).doubleValue());//BigDecimal 类型除//
//ROUND_HALF_UP: 遇到.5的情况时往上进,例: 1.5 ->;2
//ROUND_HALF_DOWN : 遇到.5的情况时往下进,例: 1.5 ->;1
}
}
--------------------------------------------------------------
BigDecimal类还有一些其他的参数,是在网上收索到的,如下:
其他参数说明
ROUND_CEILING
如果 BigDecimal 是正的,则做 ROUND_UP 操作;如果为负,则做 ROUND_DOWN 操作。
ROUND_DOWN
从不在舍弃(即截断)的小数之前增加数字。
ROUND_FLOOR
如果 BigDecimal 为正,则作 ROUND_UP ;如果为负,则作 ROUND_DOWN 。
ROUND_HALF_DOWN
若舍弃部分> .5,则作 ROUND_UP;否则,作 ROUND_DOWN 。
ROUND_HALF_EVEN
如果舍弃部分左边的数字为奇数,则作 ROUND_HALF_UP ;如果它为偶数,则作 ROUND_HALF_DOWN 。
ROUND_HALF_UP
若舍弃部分>=.5,则作 ROUND_UP ;否则,作 ROUND_DOWN 。
ROUND_UNNECESSARY
该“伪舍入模式”实际是指明所要求的操作必须是精确的,,因此不需要舍入操作。
ROUND_UP
总是在非 0 舍弃小数(即截断)之前增加数字。
---------------------------------------------------------------------
注: 也是在网上看到的有人说
BigDecimal只有构造函数为String时才能真正做到精确计算,这方面用BigDecimal.valueOf是不行的,
有人建议把需要精确的数变成一个bigInteger,没有测试,据说不能完全解决精度问题。
-----------------------------------------------------------------------------
BigDecimal性能的问题
http://users.belgacombusiness.net/arci/
看看这个,另一个BigDecimal实现,据称比java.math.BigDecimal快