美文网首页
Java BigDecimal 精确浮点型

Java BigDecimal 精确浮点型

作者: 强大帅 | 来源:发表于2021-02-26 11:39 被阅读0次

    为什么要使用BigDecimal

    说到java中的浮点型,大家主要用的还是floatdouble,但这两种浮点型的精度都是有限的,一般情况下只是一个近似值,永远不要相信浮点数结果精确到了最后一位,也永远不要相信两个浮点数是否相等。但在有些情况下,比如财务系统中,对于精度要求很高,这里Java提供了一个BigDecimal类。

    构造方法

    BigDecimal(int)       创建一个具有参数所指定整数值的对象。 
    
    BigDecimal(double) 创建一个具有参数所指定双精度值的对象。 //禁止使用
    
    BigDecimal(long)    创建一个具有参数所指定长整数值的对象。 
    
    BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。//推荐使用
    

    为何禁止使用BigDecimal(double)


    看上面代码运行结果,你就应该知道为什么不推荐使用了,因为用这种方式也会导致计算有问题

    为什么会出现这种情况呢?

    JDK的描述:1、参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。

    另一方面,String 构造方法是完全可预知的:写入 newBigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用String构造方法

    静态方法 valueOf(double val) 内部实现,仍是将 double 类型转为 String 类型; 这通常是将 double(或float)转化为 BigDecimal 的首选方法

    方法描述

    add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
    subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
    multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
    divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
    toString() 将BigDecimal对象的数值转换成字符串。
    doubleValue() 将BigDecimal对象中的值以双精度数返回。
    floatValue() 将BigDecimal对象中的值以单精度数返回。
    longValue() 将BigDecimal对象中的值以长整数返回。
    intValue() 将BigDecimal对象中的值以整数返回。

    当double必须用作BigDecimal的源时,请使用Double.toString(double)转成String,然后使用String构造方法,或使用BigDecimal的静态方法valueOf,如下

    static BigDecimal valueOf(double d); //常用,推荐使用
    

    使用方法


    这边特别提一下,如果进行除法运算的时候,结果不能整除,有余数,这个时候会报java.lang.ArithmeticException:,这边我们要避免这个错误产生,在进行除法运算的时候,针对可能出现的小数产生的计算,必须要多传两个参数
    divide(BigDecimal,保留小数点后几位小数舍入模式)

    舍入模式

    ROUND_CEILING //向正无穷方向舍入
    ROUND_DOWN //向零方向舍入
    ROUND_FLOOR //向负无穷方向舍入
    ROUND_HALF_DOWN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5
    ROUND_HALF_EVEN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP,如果是偶数,使用ROUND_HALF_DOWN
    ROUND_HALF_UP //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6,也就是我们常说的“四舍五入
    ROUND_UNNECESSARY //计算结果是精确的,不需要舍入模式
    ROUND_UP //向远离0的方向舍入

    需要对BigDecimal进行截断和四舍五入可用setScale方法,例:

    参考链接
    java 中 BigDecimal 详解

    相关文章

      网友评论

          本文标题:Java BigDecimal 精确浮点型

          本文链接:https://www.haomeiwen.com/subject/rjrmfltx.html