BigDecimal

BigDecimal

用于解决浮点型运算时,出现结果失真的问题

BigDecimal常见构造器及方法

构造器说明
public BigDecimal(double val) (不推荐)将double转换为BigDecimal
public BigDecimal(String val)把String转换成BigDecimal
方法名说明
public static BigDecimal valueOf(double val)转换一个double成BigDecimal
public BigDecimal add(BigDecimal b)加法
public BigDecimal subtract(BigDecimal b)减法
public BigDecimal multiply(BigDecimal b)乘法
public BigDecimal divide(BigDecimal b)除法
public BigDecimal divide(另一个BigDecimal对象, 精确几位, 舍入模式)除法,可以控制精确到小数几位
public double doubleValue()将BigDecimal转换为double

案例演示

public class BigDecimalTest {
    public static void main(String[] args) {
        double a = 0.1;
        double b = 0.2;
        System.out.println(a + b);  //0.30000000000000004   结果失真
        System.out.println("-----------------------------");

        //将0.1和0.2转换成字符串封装成BigDecimal对象来运算
//        BigDecimal a1 = new BigDecimal(Double.toString(a));
//        BigDecimal b1 = new BigDecimal(Double.toString(b));

        //优化,前两行代码已经被封装到valueOf()方法里
        BigDecimal a1 = BigDecimal.valueOf(a);
        BigDecimal b1 = BigDecimal.valueOf(b);

        //加法
        System.out.println(a1.add(b1)); //0.3

        //减法
        System.out.println(b1.subtract(a1));    //0.1

        //乘法
        System.out.println(a1.multiply(b1));    //0.02

        //除法
        System.out.println(b1.divide(a1));  //2

        BigDecimal c1 = BigDecimal.valueOf(0.3);
        BigDecimal d1 = BigDecimal.valueOf(0.1);
//        System.out.println(d1.divide(c1));  //异常:Non-terminating decimal expansion(无法精确表达结果,1无法除尽3,需保留精度)

        //public BigDecimal divide(另一个BigDecimal对象, 精确几位, 舍入模式)
        System.out.println(d1.divide(c1, 10, RoundingMode.HALF_UP));

        //public double doubleValue()   将BigDecimal对象转换成double类型
        double db = d1.doubleValue();
        System.out.println(d1);
    }
}

补充:BigDecimal中的8种舍入模式

BigDecimal类提供了多种舍入模式,这些模式定义在RoundingMode枚举类中

舍入模式说明
UP不论舍弃部分的数值是多少(除非是0),始终将数字舍入到远离零的方向
DOWN将数字舍入到接近零的方向,即直接截断超出精度的尾数部分,不进行四舍五入
CEILING向正无穷大方向舍入
FLOOR向负无穷大方向舍入
HALF_UP通常理解的“四舍五入”,如果舍弃部分 >= 5,则向远离零的方向舍入;否则,舍入到最近的偶数(银行家舍入法)
HALF_DOWN如果舍弃部分 > 5,则向远离零的方向舍入;否则,向零方向舍入
HALF_EVEN舍入模式向“最近邻”舍入,除非两个邻域都是等距的,在这种情况下,向偶数邻舍入。如果舍弃部分正好为5,则舍入到与前一位数字同奇偶性的数字
UNNECESSARY如果舍弃部分非零,则抛出 ArithmeticException 异常,表示不允许舍去非零部分。此模式只用于不需要舍入的情况,确保计算精确无舍入误差。

案例演示

public class RoundingModeTest {
    public static void main(String[] args) {
        //ROUND_UP
        BigDecimal up1 = new BigDecimal("123.789");

        //public BigDecimal setScale(int newScale, RoundingMode roundingMode)
        //用于设置或改变该 BigDecimal 对象的精度(小数点后的位数),同时根据指定的舍入模式进行数值的调整。
        //newScale: 整型值,表示要设定的精度。例如,如果设置为2,则结果将保留两位小数。
        //roundingMode 舍入模式
        up1 = up1.setScale(2, RoundingMode.UP);
        System.out.println(up1);  //123.79
        BigDecimal up2 = new BigDecimal("123.331");
        System.out.println(up2.setScale(2, RoundingMode.UP));    //123.34

        //ROUND_DOWN
        System.out.println("--------------------------------");
        BigDecimal down1 = new BigDecimal("123.456");
        System.out.println(down1.setScale(2, RoundingMode.DOWN));   //123.45

        //ROUND_CEILING
        System.out.println("---------------------------------");
        BigDecimal cei1 = new BigDecimal("110.353");
        System.out.println(cei1.setScale(2, RoundingMode.CEILING)); //110.36

        //ROUND_FLOOR
        System.out.println("---------------------------------");
        BigDecimal fl1 = new BigDecimal("99.847");
        System.out.println(fl1.setScale(2, RoundingMode.FLOOR));    //99.84

        //ROUND_HALF_UP
        System.out.println("---------------------------------");
        BigDecimal hu1 = new BigDecimal("144.987");
        System.out.println(hu1.setScale(2, RoundingMode.HALF_UP));  //144.99
        BigDecimal hu2 = new BigDecimal("144.984");
        System.out.println(hu2.setScale(2, RoundingMode.HALF_UP));  //144.98

        //ROUND_HALF_DOWN
        System.out.println("---------------------------------");
        BigDecimal hd1 = new BigDecimal("88.655");
        System.out.println(hd1.setScale(2, RoundingMode.HALF_DOWN));  //88.65
        BigDecimal hd2 = new BigDecimal("88.656");
        System.out.println(hd2.setScale(2, RoundingMode.HALF_DOWN));    //88.66
        BigDecimal hd3 = new BigDecimal("88.657");
        System.out.println(hd3.setScale(2, RoundingMode.HALF_DOWN));    //88.66

        //ROUND_HALF_EVEN
        System.out.println("---------------------------------");
        BigDecimal he1 = new BigDecimal("655.347");
        System.out.println(he1.setScale(2, RoundingMode.HALF_EVEN));    //655.35
        BigDecimal he2 = new BigDecimal("655.344");
        System.out.println(he2.setScale(2, RoundingMode.HALF_EVEN));    //655.34
        BigDecimal he3 = new BigDecimal("655.345");
        System.out.println(he3.setScale(2, RoundingMode.HALF_EVEN));    //655.34


        //ROUND_UNNECESSARY
        System.out.println("---------------------------------");
        BigDecimal un1 = new BigDecimal("133.455");
        try {
            System.out.println(un1.setScale(2, RoundingMode.UNNECESSARY));
        } catch (ArithmeticException e) {   //因为舍去部分非零,所以抛出ArithmeticException
            System.out.println(e.getMessage());
        }

        BigDecimal un2 = new BigDecimal("133.450");
        System.out.println(un2.setScale(2, RoundingMode.UNNECESSARY));  //133.45
    }
}

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

离歌慢饮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值