博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第二章 Java浮点数精确计算
阅读量:6554 次
发布时间:2019-06-24

本文共 2760 字,大约阅读时间需要 9 分钟。

1、实际意义

在实际开发中,如果需要进行float或double的精确计算(尤其是财务计算),直接使用float或double是不行的(具体的例子看下边的代码的main方法的测试结果),需要使用BigDecimal。

 

2、代码

package com.xxx.util;import java.math.BigDecimal;/** * 浮点数精准算法 */public class BigDecimalArithUtil {    private static final int DIV_SCALE = 10;//除法精度(除不尽时保留10为小数)        /** 小数精确加法  */    public static double add(double d1,double d2)    {        BigDecimal bd1 = BigDecimal.valueOf(d1);        BigDecimal bd2 = BigDecimal.valueOf(d2);        return bd1.add(bd2).doubleValue();    }        /** 小数精确减法  */    public static double sub(double d1,double d2)    {        BigDecimal bd1 = BigDecimal.valueOf(d1);        BigDecimal bd2 = BigDecimal.valueOf(d2);        return bd1.subtract(bd2).doubleValue();    }        /** 小数精确乘法  */    public static double mul(double d1,double d2)    {        BigDecimal bd1 = BigDecimal.valueOf(d1);        BigDecimal bd2 = BigDecimal.valueOf(d2);        return bd1.multiply(bd2).doubleValue();    }        /** 小数精确除法   */    public static double div(double d1,double d2)    {        BigDecimal bd1 = BigDecimal.valueOf(d1);        BigDecimal bd2 = BigDecimal.valueOf(d2);        /*         * 当除不尽时,以四舍五入的方式(关于除不尽后的值的处理方式有很多种)保留小数点后10位小数         */        return bd1.divide(bd2, DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();    }        public static void main(String[] args)    {        //测试加法        System.out.println("0.05+0.01="+BigDecimalArithUtil.add(0.05,0.01));        System.out.println("0.05+0.01="+(0.05+0.01));        //测试减法        System.out.println("1.0-0.42="+BigDecimalArithUtil.sub(1.0,0.42));        System.out.println("1.0-0.42="+(1.0-0.42));        //测试乘法        System.out.println("4.015*100="+BigDecimalArithUtil.mul(4.015,100));        System.out.println("4.015*100="+(4.015*100));        //测试除法        System.out.println("123.3/100="+BigDecimalArithUtil.div(123.3,100));        System.out.println("123.3/100="+(123.3/100));    }}
View Code

 

3、注意点

  • 上边的程序我用的是BigDecimal.valueOf(double x)来将double型的x封装成BigDecimal,查看源码如下:
    /**     * 注意:这通常是将double和float转换为一个BigDecimal的最好方式     */    public static BigDecimal valueOf(double val) {        return new BigDecimal(Double.toString(val));    }
    View Code

    在这里直接先将double转换为了String,然后使用如下构造方法再将String转换为BigDecimal

    public BigDecimal(String val)

    这是最好的做法。如果使用的是直接将double或float转换为BigDecimal的方式,也就是说使用的如下构造器,那么将可能得不到精确结果。(看注释)这一点可以用10.02*10.02来证明。

    /**     * 注意:The results of this constructor can be somewhat unpredictable.     * 该构造器的结果有时是不准确的     */    public BigDecimal(double val)
    View Code
  • 在实际使用中还可能使用int和long来进行浮点数的精确计算(具体做法:将浮点数先乘以相应的倍数转化为int(<=9位十进制数)或long(<=18位十进制数),计算之后再除以之前的倍数,得出结果),而且该种方式的性能会更高,具体的int、long和BigDecimal各自的使用看《Effective Java(第二版)》第48条。
  • 需要指出的是,在实际开发中,BigDecimal的性能差的问题基本可以忽略,是浮点数精确计算的首选,而且根据上一条来看,如果将浮点数转化后的整数大于18位的话,也必须用BigDecimal

转载地址:http://uatco.baihongyu.com/

你可能感兴趣的文章
Algs4-2.4.22调优先队列的整数组大小
查看>>
设计模式之建造者
查看>>
模块化的JavaScript开发的优势在哪里
查看>>
上海某软件公司电话面试分享
查看>>
TCP 和 UDP 协议发送数据包的大小 (转载)
查看>>
用Alamofire进行网络请求的一段代码解析(一)
查看>>
elasticsearch的percolator操作
查看>>
windows 定时任务:schtasks,定时关闭网易云音乐
查看>>
C# Note17: 使用Ionic.Zip.dll实现解压缩文件
查看>>
Mina Basics 06-传输
查看>>
c 编译异常 switch 之a label can only be part of a statement and a declaration is not a statement...
查看>>
nullnullDataTable 排序
查看>>
Codeforces Ilya and Queries
查看>>
NEWS - InstallShield 2013发布
查看>>
Viewport
查看>>
〖Linux〗Debian 7.1.0 Wheezy使用ltib报错的解决办法
查看>>
〖Android〗(how-to) fix k860/k860i buletooth.
查看>>
static与线程安全 -摘自网络
查看>>
jsf标签,jsp标签与jstl标签
查看>>
使用PHP CURL的POST数据
查看>>