• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
深水是沉默
别自制压力,我们没有必要跟着时间走, 只需跟着心态和能力走 随缘 尽力 问心无愧,其他的,交给天。
博客园    首页    新随笔    联系   管理    订阅  订阅
BigDecimal加减乘除计算

一、简述

在很多编程语言中,浮点数类型float和double运算会丢失精度。

二、方法介绍

BigDecimal有多种构造函数,常用的有2种。建议使用String构造方式,不建议使用double构造方

// 原则是使用BigDecimal并且一定要用String来构造。
public BigDecimal(String val);
public BigDecimal(double val);

在银行、帐户、计费等领域,BigDecimal提供了精确的数值计算。对Bigdecimal类型值进行加减乘除绝对值的运算,其实就是Bigdecimal的类方法的一些调用。

  • 加法:add()函数
  • 减法:subtract()函数
  • 乘法:multiply()函数
  • 除法:divide()函数
  • 绝对值:abs()函数
        BigDecimal valueSec = new BigDecimal(1000000);
        BigDecimal valueThi = new BigDecimal(-1000000);

        //尽量用字符串的形式初始化
        BigDecimal stringFir = new BigDecimal("0.005");
        BigDecimal stringSec = new BigDecimal("1000000");
        BigDecimal stringThi = new BigDecimal("-1000000");

        //加法
        BigDecimal addVal = valueFir.add(valueSec);
        System.out.println("加法用value结果:" + addVal);
        BigDecimal addStr = stringFir.add(stringSec);
        System.out.println("加法用string结果:" + addStr);

        //减法
        BigDecimal subtractVal = valueFir.subtract(valueSec);
        System.out.println("减法value结果:" + subtractVal);
        BigDecimal subtractStr = stringFir.subtract(stringSec);
        System.out.println("减法用string结果:" + subtractStr);

        //乘法
        BigDecimal multiplyVal = valueFir.multiply(valueSec);
        System.out.println("乘法用value结果:" + multiplyVal);
        BigDecimal multiplyStr = stringFir.multiply(stringSec);
        System.out.println("乘法用string结果:" + multiplyStr);

        //绝对值
        BigDecimal absVal = valueThi.abs();
        System.out.println("绝对值用value结果:" + absVal);
        BigDecimal absStr = stringThi.abs();
        System.out.println("绝对值用string结果:" + absStr);

        //除法
        BigDecimal divideVal = valueSec.divide(valueFir, 20, BigDecimal.ROUND_HALF_UP);
        System.out.println("除法用value结果:" + divideVal);
        BigDecimal divideStr = stringSec.divide(stringFir, 20, BigDecimal.ROUND_HALF_UP);
        System.out.println("除法用string结果:" + divideStr);

  

三、注意

  1. System.out.println()中的数字默认是double类型的,double类型小数计算不精准。
  2. 使用BigDecimal类构造方法传入double类型时,计算的结果也是不精确的。

因为不是所有的浮点数都能够被精确的表示成一个double 类型值,因此它会被表示成与它最接近的 double 类型的值。必须改用传入String的构造方法。这一点在BigDecimal类的构造方法注释中有说明。


舍入模式

  1. ROUND_UP

舍入远离零的舍入模式。在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。注意,此舍入模式始终不会减少计算值的大小。

  1. ROUND_DOWN

接近零的舍入模式。在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。注意,此舍入模式始终不会增加计算值的大小。

  1. ROUND_CEILING

接近正无穷大的舍入模式。如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;如果为负,则舍入行为与 ROUND_DOWN 相同。注意,此舍入模式始终不会减少计算值。

  1. ROUND_FLOOR

接近负无穷大的舍入模式。如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;如果为负,则舍入行为与 ROUND_UP 相同。注意,此舍入模式始终不会增加计算值。

  1. ROUND_HALF_UP

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。注意,这是我们大多数人在小学时就学过的舍入模式(四舍五入)。

  1. ROUND_HALF_DOWN

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式。如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。

  1. ROUND_HALF_EVEN

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。如果前一位为奇数,则入位,否则舍去。

以下例子为保留小数点1位,那么这种舍入方式下的结果。

1.15>1.2 1.25>1.2

  1. ROUND_UNNECESSARY

断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。



posted on 2020-05-22 11:51  深水是沉默  阅读(370)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3