BigDecimal 解析

转载自:https://www.jianshu.com/p/2947868d76eb

叙述

大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。比如:货币

使用

1、构建BigDecimal

BigDecimal BigDecimal(double d); //不允许使用,精度不能保证
BigDecimal BigDecimal(String s); //常用,推荐使用
static BigDecimal valueOf(double d); //常用,推荐使用

2、方法

方法描叙
add(BigDecimal)BigDecimal对象中的值相加,然后返回这个对象
subtract(BigDecimal)BigDecimal对象中的值相减,然后返回这个对象
multiply(BigDecimal)BigDecimal对象中的值相乘,然后返回这个对象
divide(BigDecimal)BigDecimal对象中的值相除,然后返回这个对象
toString()将BigDecimal对象的数值转换成字符串
doubleValue()将BigDecimal对象中的值以双精度数返回
floatValue()将BigDecimal对象中的值以单精度数返回
longValue()将BigDecimal对象中的值以长整数返回
intValue()将BigDecimal对象中的值以整数返回。

3、格式化和四舍五入

// 格式化:保留2为小数
DecimalFormat df = new DecimalFormat("#.##");
// 四舍五入,默认五舍六入
df.setRoundingMode(RoundingMode.HALF_UP);

4、格式化
DecimalFormat 解析:

符号位置描叙
0数字阿拉伯数字,如果不存在则显示0
#数字阿拉伯数字,如果不存在不显示0
.数字小数分隔符或货币小数分隔符
,数字分组分隔符
E数字分隔科学计数法中的尾数和指数。在前缀或后缀中无需加引号。
-数字负号
;子模式边界分隔正数和负数子模式
%前缀或后缀乘以 100 并显示为百分数
\u2030前缀或后缀乘以 1000 并显示为千分数
¤(\u00A4)前缀或后缀货币记号,由货币符号替换。如果两个同时出现,则用国际货币符号替换。如果出现在某个模式中,则使用货币小数分隔符,而不使用小数分隔符。
'前缀或后缀用于在前缀或或后缀中为特殊字符加引号,例如 "'#'#"将 123 格式化为 "#123"。要创建单引号本身,请连续使用两个单引号:"# o''clock"。

5、舍入模式介绍

  • RoundingMode.CEILNG:向正无限大方向舍入的舍入模式。如果结果为正,则舍入行为类似于 RoundingMode.UP;如果结果为负,则舍入行为类似于 RoundingMode.DOWN
    如下:
5.5  =>  6 
1.1  =>  2
-1.0  =>  -1 
-2.5  =>  -2
  • RoundingMode.DOWN:向零方向舍入的舍入模式。从不对舍弃部分前面的数字加 1(即截尾)。注意,此舍入模式始终不会增加计算值的绝对值
    如下:
5.5  =>  5 
1.1  =>  1 
-1.0  =>  -1 
-1.6  =>  -1  
  • RoundingMode.FLOOR:向负无限大方向舍入的舍入模式。如果结果为正,则舍入行为类似于 RoundingMode.DOWN;如果结果为负,则舍入行为类似于 RoundingMode.UP
    注意:此舍入模式始终不会增加计算值
    如下:
5.5  =>  5 
2.3  =>  2
1.0  =>  1 
-1.1  =>  -2 
-2.5  =>  -3 
  • RoundingMode.HALF_DOWN :向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。如果被舍弃部分 > 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同 RoundingMode.DOWN
    五舍六入
    如下:
2.5  =>  2 
1.6  =>  2
-1.1  =>  -1 
-1.6  =>  -2
-2.5  =>  -2
  • RoundingMode.HALF_EVEN :向 最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为同 RoundingMode.HALF_UP;如果为偶数,则舍入行为同 RoundingMode.HALF_DOWN。注意,在重复进行一系列计算时,此舍入模式可以在统计上将累加错误减到最小。此舍入模式也称为“银行家舍 入法”,主要在美国使用。此舍入模式类似于 Java 中对 float 和 double 算法使用的舍入策略
    如下:
5.5  =>  6 
2.5  =>  2 
1.1  =>  1 
-1.0  =>  -1 
-1.6  =>  -2 
-2.5  =>  -2
  • RoundingMode.HALF_UP :向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。如果被舍弃部分 >= 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同 RoundingMode.DOWN
    注意:此舍入模式就是通常学校里讲的四舍五入
    如下:
2.5  =>  3 
1.1  =>  1 
-1.1  =>  -1 
-1.6  =>  -2 
  • RoundingMode.UNNECESSARY :用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。如果对生成精确结果的操作指定此舍入模式,则抛出 ArithmeticException
    如下:
1.5  =>  抛出 ArithmeticException
1.1  =>  抛出 ArithmeticException
1.0  =>  1
-1.1  =>抛出 ArithmeticException 
-1.6  =>  抛出 ArithmeticException 
  • RoundingMode.UP :远离零方向舍入的舍入模式。始终对非零舍弃部分前面的数字加 1。注意,此舍入模式始终不会减少计算值的绝对值
    如下:
5.5  =>  6 
1.1  =>  2 
-1.1  =>  -2 
-1.6  =>  -2 

问题

  1. BigDecimal的divide方法进行除法时当不整除,出现无限循环小数时,就会抛异常的,异常如下:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. at java.math.BigDecimal.divide(Unknown Source)

解决方法:给divide设置精确的小数点

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值