BigDecimal可以理解为一个浮点数, 其大小可任意指定而且精度准确, 故日常用在金额,利息等金钱相关的字段上,因最近使用较多,故记录一下,给大家参考一下,避免其中的问题.
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关键字修饰,不能修改,表示小数位数.
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.
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());
总结:
1 一个 BigDecimal对象的scale()
方法返回负数, 如-2,表示这个数是整数,结尾有2个0
2 一个BigDecimal对象结尾没有0,再调用stripTrailingZeros()方法,得到的结果不变.
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
,分别是商和余数,其中商总是整数,余数不会大于除数.
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值相等,还要求两个对象的小数位相等.
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()
!
今天的文章BigDecimal的使用分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/18404.html