double、float数值运算出现精度问题的解决方式

来源:互联网 发布:想做淘宝主播要培训吗 编辑:程序博客网 时间:2024/05/16 08:44

  最近在一直在写有关自定义View的demo,有时候绘制的View的高和我实际的结果有偏差,之前就听同事说过用java.math的BigDecimal类进行处理会更准确,今天正好有空就顺便整理下。首先写了一个DecimalUtil做测试,代码如下:

/** * 加运算 */public static double addOne(double a, double b) {    return a + b;}public static double addTwo(double a, double b) {    BigDecimal bd1 = new BigDecimal(Double.toString(a));    BigDecimal bd2 = new BigDecimal(Double.toString(b));    return bd1.add(bd2).doubleValue();}/** * 减运算 */public static double subOne(double a, double b) {    return a - b;}public static double subTwo(double a, double b) {    BigDecimal bd1 = new BigDecimal(Double.toString(a));    BigDecimal bd2 = new BigDecimal(Double.toString(b));    return bd1.subtract(bd2).doubleValue();}/** * 乘运算 */public static double mulOne(double a, double b) {    return a * b;}public static double mulTwo(double a, double b) {    BigDecimal bd1 = new BigDecimal(Double.toString(a));    BigDecimal bd2 = new BigDecimal(Double.toString(b));    return bd1.multiply(bd2).doubleValue();}/** * 除运算 */public static double divOne(double a, double b) {    return a / b;}public static double divTwo(double a, double b) {    BigDecimal aBD = new BigDecimal(Double.toString(a));    BigDecimal bBd = new BigDecimal(Double.toString(b));    return aBD.divide(bBd, 20, BigDecimal.ROUND_HALF_UP).doubleValue();}
System.out.print("加"+DecimalUtil.addOne(0.05,0.025)+"--"+DecimalUtil.addTwo(0.05,0.025));System.out.print("减"+DecimalUtil.subOne(0.05,0.025)+"--"+DecimalUtil.subTwo(0.05,0.025));System.out.print("乘"+DecimalUtil.mulOne(0.05,0.025)+"--"+DecimalUtil.mulTwo(0.05,0.025));System.out.print("除"+DecimalUtil.divOne(0.05,0.025)+"--"+DecimalUtil.divTwo(0.05,0.025));

运行上面的代码,在控制台打印结果如下:


这里我们可以看到输出结果对比,浮点型数据直接运算和我们想要的结果还是有一定的误差,这里主要说明一下divide(BigDecimal divisor,int scale,int roundingMode)这个方法,scale表示保留到小数点后几位,roundingMode表示保留模式,一个提供了7种,这里就不详细说明了。还有divide(BigDecimal divisor)这个方法,这个适用于整除的两个浮点型数,非整除就不能使用,否则会报java.lang.ArithmeticException的异常。

最后说一下BigDecimal的格式化问题,由于NumberFormat的format()方法可以使用BigDecimal对象作为参数,可以使用BigDecimal对超出16位有效数字的货币值、百分比值、以及一般数值进行格式化控制。下面贴出测试的代码:

public static void format(){    NumberFormat currency = NumberFormat.getCurrencyInstance();  //建立货币格式化引用    NumberFormat percent = NumberFormat.getPercentInstance();    //建立百分比格式化引用    percent.setMaximumFractionDigits(3);                         //百分比小数点最多3位    BigDecimal loanAmount = new BigDecimal(Double.toString(100000.009));  //贷款金额    BigDecimal interestRate = new BigDecimal(Double.toString(0.06));      //利率    BigDecimal interest = loanAmount.multiply(interestRate);              //相乘    System.out.println("贷款金额:" + currency.format(loanAmount));    System.out.println("利率:" + percent.format(interestRate));    System.out.println("利息:" + currency.format(interest));}

输出结果如下,


这里只是简单的分享了下解决方式,有兴趣的同学还可以深入了解下!

原创粉丝点击