关于MathContext和RoundingMode的简单介绍

对于用过BigDecimal的人来说,一定遇到过MathContext这个对象吧?我遇到的时候也是一脸懵逼,为了搞清楚什么是MathContext我查了很多的书籍,也看了很多的博客,发现想搞懂MathContext还必须先搞懂RoundingMode,于是我又不得不查RoundingMode的相关。现在大致有了一点眉目。下面就简单说一下,希望对大家能有所帮助。

RoundingMode

对于RoundingMode来说,大概就是对舍入模式的抽象。这是一个枚举类,点开源码后可以发现声明了如下的几个枚举值:

  • UP(BigDecimal.ROUND_UP):直接进位处理

关于UP的测试代码如下:

public class RoundingModeTest{

    public static void main(String[] args) {

        BigDecimal b = BigDecimal.valueOf(12.3459);
        BigDecimal b2 = BigDecimal.valueOf(12.3451);
        BigDecimal b3 = BigDecimal.valueOf(12.3455);
        System.out.println("采用Rounding.UP得到的结果:" + b.setScale(3, RoundingMode.UP));
        System.out.println("采用Rounding.UP得到的结果:" + b2.setScale(3, RoundingMode.UP));
        System.out.println("采用Rounding.UP得到的结果:" + b3.setScale(3, RoundingMode.UP));
    }
}

执行结果如下图所示:

  • DOWN(BigDecimal.ROUND_DOWN):舍弃不需要的小数位

示例代码如下所示:

public class RoundingModeTest{

    public static void main(String[] args) {

        BigDecimal b = BigDecimal.valueOf(12.3459);
        BigDecimal b2 = BigDecimal.valueOf(12.3451);
        BigDecimal b3 = BigDecimal.valueOf(12.3455);
        System.out.println("采用Rounding.DOWN得到的结果:" + b.setScale(3, RoundingMode.DOWN));
        System.out.println("采用Rounding.DOWN得到的结果:" + b2.setScale(3, RoundingMode.DOWN));
        System.out.println("采用Rounding.DOWN得到的结果:" + b3.setScale(3, RoundingMode.DOWN));
    }
}

执行结果如下图所示:

  • CEILING(BigDecimal.ROUND_CEILING):舍去不需要的小数位,再最后一位进1

示例代码如下所示:

public class RoundingModeTest{

    public static void main(String[] args) {

        BigDecimal b = BigDecimal.valueOf(12.3459);
        BigDecimal b2 = BigDecimal.valueOf(12.3451);
        BigDecimal b3 = BigDecimal.valueOf(12.3455);
        System.out.println("采用Rounding.CEILING得到的结果:" + b.setScale(3, RoundingMode.CEILING));
        System.out.println("采用Rounding.CEILING得到的结果:" + b2.setScale(3, RoundingMode.CEILING));
        System.out.println("采用Rounding.CEILING得到的结果:" + b3.setScale(3, RoundingMode.CEILING));
    }
}

执行结果如下图所示:

  • FLOOR(BigDecimal.ROUND_FLOOR):直接舍去不需要的小数位

示例代码如下所示:

public class RoundingModeTest{

    public static void main(String[] args) {

        BigDecimal b = BigDecimal.valueOf(12.3459);
        BigDecimal b2 = BigDecimal.valueOf(12.3451);
        BigDecimal b3 = BigDecimal.valueOf(12.3455);
        System.out.println("采用Rounding.FLOOR得到的结果:" + b.setScale(3, RoundingMode.FLOOR));
        System.out.println("采用Rounding.FLOOR得到的结果:" + b2.setScale(3, RoundingMode.FLOOR));
        System.out.println("采用Rounding.FLOOR得到的结果:" + b3.setScale(3, RoundingMode.FLOOR));
    }
}

执行结果如下图所示:

  • HALF_UP(BigDecimal.ROUND_HALF_UP):舍去不需要的小数位,向保留小数位最近的数字靠近。距离相等时,直接舍去小数位,在现有保留小数位的最低位加1.

示例代码如下所示:

public class RoundingModeTest{

    public static void main(String[] args) {

        BigDecimal b = BigDecimal.valueOf(12.3459);
        BigDecimal b2 = BigDecimal.valueOf(12.3451);
        BigDecimal b3 = BigDecimal.valueOf(12.3455);
        System.out.println("采用Rounding.HALF_UP得到的结果:" + b.setScale(3, RoundingMode.HALF_UP));
        System.out.println("采用Rounding.HALF_UP得到的结果:" + b2.setScale(3, RoundingMode.HALF_UP));
        System.out.println("采用Rounding.HALF_UP得到的结果:" + b3.setScale(3, RoundingMode.HALF_UP));
    }
}

执行结果如下图所示:

  • HALF_DOWN(BigDecimal.ROUND_HALF_DOWN):舍去不需要的小数位,向保留小数位最近的数字靠近。距离相等时,直接舍去小数位。

示例代码如下所示:

public class RoundingModeTest {

    public static void main(String[] args) {

        BigDecimal b = BigDecimal.valueOf(12.3459);
        BigDecimal b2 = BigDecimal.valueOf(12.3451);
        BigDecimal b3 = BigDecimal.valueOf(12.3455);
        System.out.println("采用Rounding.HALF_DOWN得到的结果:" + b.setScale(3, RoundingMode.HALF_DOWN));
        System.out.println("采用Rounding.HALF_DOWN得到的结果:" + b2.setScale(3, RoundingMode.HALF_DOWN));
        System.out.println("采用Rounding.HALF_DOWN得到的结果:" + b3.setScale(3, RoundingMode.HALF_DOWN));
    }
}

执行结果如下图与所示:

  • HALF_EVEN(BigDecimal.ROUND_HALF_EVEN)::舍去不需要的小数位,向保留小数位最近的数字靠近。距离相等时,向现有保留小数位的最低位是偶数的靠近。

示例代码如下所示:

public class RoundingModeTest{

    public static void main(String[] args) {

        BigDecimal b = BigDecimal.valueOf(12.3459);
        BigDecimal b2 = BigDecimal.valueOf(12.3451);
        BigDecimal b3 = BigDecimal.valueOf(12.3455);
        BigDecimal b4 = BigDecimal.valueOf(12.3445);
        System.out.println("采用Rounding.HALF_EVEN得到的结果:" + b.setScale(3, RoundingMode.HALF_EVEN));
        System.out.println("采用Rounding.HALF_EVEN得到的结果:" + b2.setScale(3, RoundingMode.HALF_EVEN));
        System.out.println("采用Rounding.HALF_EVEN得到的结果:" + b3.setScale(3, RoundingMode.HALF_EVEN));
        System.out.println("采用Rounding.HALF_EVEN得到的结果:" + b4.setScale(3, RoundingMode.HALF_EVEN));
    }
}

执行结果如下图所示:

  • UNNECESSARY(BigDecimal.ROUND_UNNECESSARY):不需要舍入

对于该模式来说,如果要求保留位数小于实际位数则会抛出算术异常。

仔细观察后发现,RoundingMode其实就是对BigDecimal中各种舍入常量值的封装。当然,单独讨论RoundingMode是没有任何意义的,它需要和MathContext配合使用。

MathContext

对于MathContext类来说,我就简单粗暴的称为数学上下文吧。因为我英语是个二把刀。MathContext所做的事就是封装舍入模式对象RoundingMode和处理位数precision。

MathContext的构造器有三个:

  1. public MathContext(int setPrecision):传入所占位数
  2. public MathContext(int setPrecision, RoundingMode setRoundingMode):传入所占位数和舍入模式
  3. public MathContext(String val):传入字符串,需要说明的是,该字符串必须是另一个MathContext对象调用toString方法后得到的字符串。

示例代码如下所示:

public class MathContextTest {

    public static void main(String[] args) {

        MathContext mc1 = new MathContext(12);
        MathContext mc2 = new MathContext(13, RoundingMode.FLOOR);
        MathContext mc3 = new MathContext(mc1.toString());
    }
}

对于MathContext来说常用的方法有:

  1. public int getPrecision():获取所占位数
  2. public RoundingMode getRoundingMode():获取舍入模式
  3. public java.lang.String toString():转换为字符串

示例代码如下所示:

public class MathContextTest {

    public static void main(String[] args) {

        MathContext mc = new MathContext(13, RoundingMode.FLOOR);
        System.out.println("mc的precision:" + mc.getPrecision());
        System.out.println("mc的RoundingMode:" + mc.getRoundingMode());
    }
}

执行结果如下图所示:

与RoundingMode一样,单独讨论MathContext也没有太大的意义,主要是配合BigDecimal来进行使用。关于MathContext和RoundingMode的介绍就说这么多。

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值