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

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

作者: v587的毅哥 | 来源:发表于2017-03-07 11:11 被阅读1817次

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

    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.86

    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.0

    eg7:

    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/nhapgttx.html