BigDecimal 用法详解



BigDecimal简介

Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。


BigDecimal用法:

BigDecimal创建的是对象,不能使用+,-,*,/等算术运算,必须调用它对应的相关方法。

并且,方法中的参数也必须是BigDecimal对象。

BigDecimal的构造方法

  1. BigDecimal(int) 创建一个具有参数所指定整数值的对象。
  2. BigDecimal(double) 创建一个具有参数所指定双精度值的对象。
  3. BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
  4. BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。
BigDecimal b = new BigDecimal(0);
BigDecimal b = new BigDecimal(1.2);
BigDecimal b = new BigDecimal("2.3");

String 构造方法是完全可预知的:写入 newBigDecimal(“0.1”) 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言, 通常建议优先使用String构造方法。

当double必须用作BigDecimal的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用Double.toString(double)方法,然后使用BigDecimal(String)构造方法,将double转换为String。要获取该结果,请使用static valueOf(double)方法。

BigDecimal常用方法描述

  1. add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
  2. subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
  3. multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
  4. divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
  5. toString() 将BigDecimal对象的数值转换成字符串。
  6. doubleValue() 将BigDecimal对象中的值以双精度数返回。
  7. floatValue() 将BigDecimal对象中的值以单精度数返回。
  8. longValue() 将BigDecimal对象中的值以长整数返回。
  9. intValue() 将BigDecimal对象中的值以整数返回。
item.setScore(
    (value.multiply(lmd).add((statuValue.divide(targetValue,3,RoundingMode.HALF_UP))
    .multiply(lmd))).multiply(new BigDecimal(100))
);

BigDecimal格式化

由于NumberFormat类的format()方法可以使用BigDecimal对象作为其参数,可以利用BigDecimal对超出16位有效数字的货币值,百分值,以及一般数值进行格式化控制。

以利用BigDecimal对货币和百分比格式化为例。首先,创建BigDecimal对象,进行BigDecimal的算术运算后,分别建立对货币和百分比格式化的引用,最后利用BigDecimal对象作为format()方法的参数,输出其格式化的货币值和百分比。

public static void main(String[] args) {  
    NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用   
    NumberFormat percent = NumberFormat.getPercentInstance();  //建立百分比格式化引用   
    percent.setMaximumFractionDigits(3); //百分比小数点最多3位   

    BigDecimal loanAmount = new BigDecimal("15000.48"); //贷款金额  
    BigDecimal interestRate = new BigDecimal("0.008"); //利率     
    BigDecimal interest = loanAmount.multiply(interestRate); //相乘  

    System.out.println("贷款金额:\t" + currency.format(loanAmount));   
    System.out.println("利率:\t" + percent.format(interestRate));   
    System.out.println("利息:\t" + currency.format(interest));   
}  

//贷款金额: ¥15,000.48 利率: 0.8% 利息: ¥120.00

BigDecimal比较

publicstaticvoidmain(String[]args){  
    BigDecimala=newBigDecimal("1");  
    BigDecimalb=newBigDecimal("2");  
    BigDecimalc=newBigDecimal("1");  
    intresult1=a.compareTo(b);  
    intresult2=a.compareTo(c);  
    intresult3=b.compareTo(a);  
    System.out.println(result1);  
    System.out.println(result2);  
    System.out.println(result3);  
} 

// -1   0  1

即左边比右边数大,返回1,相等返回0,比右边小返回-1。注意 不可用equals进行相等的判断,equals 比较是两个BigDecimal对象的地址。


BigDecimal总结

在需要精确的小数计算时再使用BigDecimal,BigDecimal的性能比double和float差,在处理庞大,复杂的运算时尤为明显。故一般精度的计算没必要使用BigDecimal。

尽量使用参数类型为String的构造函数。

BigDecimal都是不可变的(immutable)的, 在进行每一次四则运算时,都会产生一个新的对象 ,所以在做加减乘除运算时要记得要保存操作后的值。

在使用BigDecimal做除法(.divide)运算时,如果结果为一个除不尽的数字,则会抛出异常:

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

所以,这是必须使用构造模型来格式化小数点:


b.divide(new BigDecimal(3),2,BigDecimal.ROUND_HALF_UP);   
BigDecimal.setScale();//用于格式化小数点     
setScale(1);//表示保留以为小数,默认用四舍五入方式     
setScale(1,BigDecimal.ROUND_DOWN);//直接删除多余的小数位,如2.35会变成2.3     
setScale(1,BigDecimal.ROUND_UP);//进位处理,2.35变成2.4     
setScale(1,BigDecimal.ROUND_HALF_UP);//四舍五入,2.35变成2.4    
setScaler(1,BigDecimal.ROUND_HALF_DOWN);//四舍五入,2.35变成2.3,如果是5则向下舍 

1、ROUND_UP
2.舍入远离零的舍入模式。
3.在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。
4.注意,此舍入模式始终不会减少计算值的大小。
5.2、ROUND_DOWN
6.接近零的舍入模式。
7.在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。
8.注意,此舍入模式始终不会增加计算值的大小。
9.3、ROUND_CEILING
10.接近正无穷大的舍入模式。
11.如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;
12.如果为负,则舍入行为与 ROUND_DOWN 相同。
13.注意,此舍入模式始终不会减少计算值。
14.4、ROUND_FLOOR
15.接近负无穷大的舍入模式。
16.如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;
17.如果为负,则舍入行为与 ROUND_UP 相同。
18.注意,此舍入模式始终不会增加计算值。
19.5、ROUND_HALF_UP
20.向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式。
21.如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。
22.注意,这是我们大多数人在小学时就学过的舍入模式(四舍五入)。
23.6、ROUND_HALF_DOWN
24.向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式。
25.如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。
26.7、ROUND_HALF_EVEN
27.向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
28.如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;
29.如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。
30.注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。
31.此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。
32.如果前一位为奇数,则入位,否则舍去。
33.以下例子为保留小数点1位,那么这种舍入方式下的结果。
34.1.15>1.2 1.25>1.2
35.8、ROUND_UNNECESSARY
36.断言请求的操作具有精确的结果,因此不需要舍入。
37.如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。







相关内容来源:
BigDecimal用法详解

BigDecimal之除不尽报错

BigDecimal除法精确计算及坑点

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值