BigDecimal的使用

BigDecimal能够理解为一个浮点数, 其大小可任意指定并且精度准确, 故平常用在金额,利息等金钱相关的字段上,因最近使用较多,故记录一下,给你们参考一下,避免其中的问题.java

1 常见使用方式构造方法

// 使用字符串,不会出现精度损失 (推荐)
// 结果: 0.1
 BigDecimal bigDecimal = new BigDecimal("0.1"); 

// 使用int整数,会出现精度损失
// 结果: 0.1000000000000000055511151231257827021181583404541015625
 BigDecimal bigDecimal2 = new BigDecimal(0.1);
复制代码

ps: String和BigDecimal互相转换数组

// 字符串转BigDecimal
String str = "100.01";
BigDecimal bigDecimal = new BigDecimal(str); 

// BigDecimal转字符串
BigDecimal big = new BigDecimal("13.14"); 
String string = big.toString();
String string2 = String.valueOf(big);
复制代码

2 BigDecimal中scale使用

1 scale说明

scale是BigDecimal的一个成员属性,final关键字修饰,不能修改,表示小数位数.markdown

BigDecimal d1 = new BigDecimal("12.10");
        BigDecimal d2 = new BigDecimal("123.1000");
        BigDecimal d3 = new BigDecimal("1234500");
		// 小数位 2
        System.out.println(d1.scale()); 
		// 小数位 4
        System.out.println(d2.scale()); 
`		// 小数位 0 
        System.out.println(d3.scale()); 
复制代码

2 stripTrailingZeros()方法使用

BigDecimal中stripTrailingZeros()方法,能够转换成一个新的BigDecimal,去掉了末尾的数字0.ide

BigDecimal d1 = new BigDecimal("123.4500");
        BigDecimal d2 = d1.stripTrailingZeros();
		// 小数位 4
        System.out.println(d1.scale()); 
		// 小数位 2,由于去掉了00
        System.out.println(d2.scale()); 

        BigDecimal d3 = new BigDecimal("1234500");
        BigDecimal d4 = d3.stripTrailingZeros();
		// 小数位 0
        System.out.println(d3.scale()); 
		// 小数位 -2
        System.out.println(d4.scale()); 
复制代码

总结:spa

1 一个 BigDecimal对象的scale()方法返回负数, 如-2,表示这个数是整数,结尾有2个0code

2 一个BigDecimal对象结尾没有0,再调用stripTrailingZeros()方法,获得的结果不变.orm

3 精度转换

类型 说明
ROUND_DOWN 去掉多余的位数
ROUND_UP 向前进位处理
ROUND_CEILING 若是是正数,就是ROUND_UP ; 若是是负数,就是ROUND_DOWN
ROUND_FLOOR 若是是正数,就是ROUND_DOWN ; 若是是负数,就是ROUND_UP
ROUND_HALF_UP 四舍五入,大于等于5,就进位(>=5)
ROUND_HALF_DOWN 四舍五入,大于5,才进位(>5)
ROUND_HALF_EVEN 若是舍弃部分左边的数字为偶数,为HALF_DOWN ; 若是舍弃部分左边的数字为奇数,为ROUND_HALF_UP
ROUND_UNNECESSARY 断言请求的操做具备精确的结果,所以不须要舍入
// 关于模式,旧的和新的描述不同,但效果一致
        // 直接去掉多余的位数
        // 1 RoundingMode.DOWN == BigDecimal.ROUND_DOWN 
        BigDecimal b = new BigDecimal("2.225667").setScale(2, BigDecimal.ROUND_DOWN);
        System.out.println(b);

        // 跟上面相反,进位处理
        // 2 RoundingMode.UP == BigDecimal.ROUND_UP
        BigDecimal c = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_UP);
        System.out.println(c);

        // 若是是正数,至关于BigDecimal.ROUND_UP ; 若是是负数,至关于BigDecimal.ROUND_DOWN
        // 3 RoundingMode.CEILING == BigDecimal.ROUND_CEILING
        BigDecimal f = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_CEILING);
        System.out.println(f);
        BigDecimal g = new BigDecimal("-2.225667").setScale(2, BigDecimal.ROUND_CEILING);
        System.out.println(g);

        // 若是是正数,至关于BigDecimal.ROUND_DOWN ; 若是是负数,至关于BigDecimal.ROUND_HALF_UP
        // 4 RoundingMode.FLOOR == BigDecimal.ROUND_FLOOR
        BigDecimal h = new BigDecimal("2.225667").setScale(2, BigDecimal.ROUND_FLOOR);
        System.out.println(h);
        BigDecimal i = new BigDecimal("-2.224667").setScale(2, BigDecimal.ROUND_FLOOR);
        System.out.println(i);

        // 四舍五入(若舍弃部分>=.5,就进位)
        // 5 RoundingMode.HALF_UP == BigDecimal.ROUND_HALF_UP
        BigDecimal d = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_UP);
        System.out.println("ROUND_HALF_UP" + d);

        // 四舍五入(若舍弃部分>.5,就进位)
        // 6 RoundingMode.HALF_DOWN == BigDecimal.ROUND_HALF_DOWN
        BigDecimal e = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_DOWN);
        System.out.println("ROUND_HALF_DOWN" + e);

        // 若是舍弃部分左边的数字为偶数,则做 ROUND_HALF_DOWN ; 若是舍弃部分左边的数字为奇数,则做 ROUND_HALF_UP
        // 7 RoundingMode.HALF_EVEN == BigDecimal.ROUND_HALF_EVEN
        BigDecimal j = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_EVEN);
        System.out.println(j);
        BigDecimal k = new BigDecimal("2.215").setScale(2, BigDecimal.ROUND_HALF_EVEN);
        System.out.println(k);


        // 断言请求的操做具备精确的结果,所以不须要舍入。若是对得到精确结果的操做指定此舍入模式,则抛出ArithmeticException。
        // 8 RoundingMode.UNNECESSARY == BigDecimal.ROUND_UNNECESSARY
        BigDecimal bigDecimal = new BigDecimal("2.215").setScale(3, BigDecimal.ROUND_UNNECESSARY);
        System.out.println(bigDecimal);


复制代码

3 BigDecimal的运算

1 加减乘除

计算加、减、乘,不会有精度丢失,除法运算时,若是存在没法除尽,须要指定精度.对象

BigDecimal n = new BigDecimal("123.456");
        BigDecimal m = new BigDecimal("23.456789");

        // 加法
        System.out.println(n.add(m));
        // 减法
        System.out.println(n.subtract(m));
        // 乘法
        System.out.println(n.multiply(m));
        // 除法
        // 报错:ArithmeticException,由于除不尽
	   // System.out.println(n.divide(m));
        // 保留10位小数并四舍五入
        System.out.println(n.divide(m, 10, RoundingMode.HALF_UP));
复制代码

2 divideAndRemainder()方法

返回的数组包含两个BigDecimal,分别是商和余数,其中商老是整数,余数不会大于除数.ip

BigDecimal n = new BigDecimal("12.75");
        BigDecimal m = new BigDecimal("0.15");
        BigDecimal[] dr = n.divideAndRemainder(m);
        if (dr[1].signum() == 0) {
            System.out.println("n是m的整数倍");
        }

        System.out.println(dr[0]);
        System.out.println(dr[1]);
复制代码

3 compareTo()方法

比较两个BigDecimal, 不要使用==equals()方法==,由于==equals()方法==既要求两个BigDecimal值相等,还要求两个对象的小数位相等.ci

BigDecimal d1 = new BigDecimal("123.1");
        BigDecimal d2 = new BigDecimal("123.10");
        
        // false,由于scale不一样
        System.out.println(d1.equals(d2));
        // true,由于d2去除尾部0后scale变为2
        System.out.println(d1.equals(d2.stripTrailingZeros())); 
复制代码

BigDecimal的比较, 须要使用==compareTo()方法==, 根据两个对象比较的结果返回负数,0和正数

// 相等 0
        BigDecimal d1 = new BigDecimal("123.1");
        BigDecimal d2 = new BigDecimal("123.1");
        System.out.println(d1.compareTo(d2));

        // 大于 1
        BigDecimal d3 = new BigDecimal("123.2");
        BigDecimal d4 = new BigDecimal("123.1");
        System.out.println(d3.compareTo(d4));

        // 小于 -1
        System.out.println(d4.compareTo(d3));
复制代码

在使用中,尽可能靠近0去作判断比较, 据说可能会出现比较结果为小数的状况, 可是博主暂时没有发现.

注意:

​ 老是使用compareTo()比较两个BigDecimal的值,不要使用equals()

相关文章
相关标签/搜索