美文网首页
关于BigDecimal.divide()的精度问题

关于BigDecimal.divide()的精度问题

作者: 寻Sweet | 来源:发表于2019-01-29 17:34 被阅读0次

    网上随便一搜,是这么写的:

    ROUND_CEILING
    Rounding mode to round towards positive infinity.
    向正无穷方向舍入

    ROUND_DOWN
    Rounding mode to round towards zero.
    向零方向舍入

    ROUND_FLOOR
    Rounding mode to round towards negative infinity.
    向负无穷方向舍入

    ROUND_HALF_DOWN
    Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.
    向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5

    ROUND_HALF_EVEN
    Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor.
    向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP ,如果是偶数,使用ROUND_HALF_DOWN

    ROUND_HALF_UP
    Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
    向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6

    ROUND_UNNECESSARY
    Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary.
    计算结果是精确的,不需要舍入模式

    ROUND_UP
    Rounding mode to round away from zero.
    向远离0的方向舍入

    MathContext mathContext = new MathContext(2,RoundingMode.UP);
    BigDecimal test1 = BigDecimal.valueOf(19785.076);
    BigDecimal test2 =BigDecimal.valueOf(100.0d);LogUtil.i("result="+test1.divide(test2,mathContext).doubleValue());

    结果是多少?
    200.0

    奇怪了,为什么是200.0?其实我的目的是想结果为:197.86。因为我是这么想的:保留2位小数,然后小数的2位之后如果还有数(也就是说后面的大于0),那么会进1位。

    但结果就是200.0,后来查了一下那MathContext里面的2并不是指保留2位小数,而是指的有效位数。所以BigDecimal.divide(BigDecimical,MathContext)就不能用了。直接用BigDecimal.divide(BigDecimaldivisor,RoundingModeroundingMode).setScale(intnewScale,RoundingModeroundingMode)来解决问题。

    但是,直接用BigDecimal.divide(BigDecimaldivisor,RoundingModeroundingMode)那么它是保留几位呢?懒得看源码,简单测试了一下,结果是:

    eg1:
    BigDecimal test1 = BigDecimal.valueOf(19785.076);
    BigDecimal test2 = BigDecimal.valueOf(100.0d);
    LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.851

    eg2:
    BigDecimal test1 = BigDecimal.valueOf(19785.070);
    BigDecimal test2 = BigDecimal.valueOf(100.0d);
    LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.85

    eg3:

    BigDecimal test1 = BigDecimal.valueOf(19785.006);
    BigDecimal test2 = BigDecimal.valueOf(100.0d);
    LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.851

    eg4:
    BigDecimal test1 = BigDecimal.valueOf(19785.06);
    BigDecimal test2 = BigDecimal.valueOf(100.0d);
    LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.86

    eg5:
    BigDecimal test1 = BigDecimal.valueOf(19785.1);
    BigDecimal test2 =BigDecimal.valueOf(100.0d);LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.9

    eg6:BigDecimal test1 = BigDecimal.valueOf(19785);
    BigDecimal test2 =BigDecimal.valueOf(100.0d);LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:198.

    0eg7:
    BigDecimal test1 = BigDecimal.valueOf(19785);
    BigDecimal test2 =BigDecimal.valueOf(100);LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:198.0

    eg8:
    BigDecimal test1 = BigDecimal.valueOf(19785);
    BigDecimal test2 =BigDecimal.valueOf(100.01);LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:198.0

    eg9:
    BigDecimal test1 = BigDecimal.valueOf(19785);
    BigDecimal test2 =BigDecimal.valueOf(100.11);LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:198.0

    eg10:
    BigDecimal test1 = BigDecimal.valueOf(19785);
    BigDecimal test2 =BigDecimal.valueOf(100.91);LogUtil.i("result="+test1.divide(test2,RoundingMode.UP).doubleValue());//输出:197.0

    发现规律了吗?

    RoundingMode:

    1、除数的小数点位数与结果的位数直接相关联,而被除数的小数点位数与结果的位数没有啥关系(至少简单测试一下看上去是这样),但是被除数的小数位数不是说没有用,而是对结果与直接关联。
    2、除数如果是N位小数,那么结果就会是N位小数。但有2个例外:①除数如果没有小数,在BigDecimal后面再继续用doubleValue会发现有xxx.0出现;②除数的最后1位如果为0,那么就会被忽略。如上eg2与eg3。
    先不写了。反正就没打算给别人看的,自己记录一下就OK了,所以也没啥排版,知识也不够全面。

    相关文章

      网友评论

          本文标题:关于BigDecimal.divide()的精度问题

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