BigDecimal 用法详解

标签: BigDecimal相关用法
16人阅读 评论(0) 收藏 举报
分类:



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除法精确计算及坑点

查看评论

BigDecimal+BigInteger

BigDecimal:不可变的、任意精度的有符号十进制数,可以解决数据丢失问题。适用于为了能精确的表示、计算浮点数。 常用方法: public BigDecimal add(BigDecimal a...
  • zhou920786312
  • zhou920786312
  • 2017-04-03 02:39:27
  • 215

BigDecimal 加减乘除+比较大小

1.BigDecimal 比较大小BigDecimal a = new BigDecimal("1.00");BigDecmial b = new BigDecimal(1);想比...
  • zhangyufeng0126
  • zhangyufeng0126
  • 2018-04-03 09:47:43
  • 14

JAVA BigDecimal的一些用法

BigDecimal的比较大小; int a = bigdemical.compareTo(bigdemical2) a = -1,表示bigdemical小于bigdemical2; a = 0,...
  • github_36859217
  • github_36859217
  • 2018-02-01 15:46:50
  • 121

JAVA浮点型的加法

  • 2012年03月24日 02:02
  • 228B
  • 下载

BigDecimal类+大整数操作

BigDecimal类 java.math.BigDecimal 用来处理高精度计算。可存浮点数。对应的整型类为BigInteger 几个比较重要的函数:  BigDecimal ad...
  • u013948187
  • u013948187
  • 2015-07-10 12:09:16
  • 627

BigDecimal(double)

“BigDecimal(double)” should not be used 级别:bug Because of floating point imprecision, you’re ...
  • xiaoidea
  • xiaoidea
  • 2016-08-30 00:54:14
  • 643

BigDecimal的用法

  • 2013年06月06日 09:53
  • 7KB
  • 下载

BigDecimal用法总结

BigDecimal常用于金额的计算,下面总结下这次项目中BigDecimal的用法。 1.加减乘除 2.设置精度 3.取反 加减乘除分别调用函数 public BigDecimal ...
  • Augus3344
  • Augus3344
  • 2016-05-31 18:19:11
  • 12490

Java中高精度问题的bigdecimal解决方式

最近有空写了点老的J2EE的代码,发现有一个十分有意思的问题,当用Hibernate从数据库里把浮点数读取出来的时候做一些比如累加的工作,例如 summary 或者递减之类的,就会发现在最后的结果中会...
  • xorxos
  • xorxos
  • 2015-04-13 14:42:00
  • 375

StringUtils.isNotBlank 和 StringUtils.isNotEmpty 以及 (""+null)不为空的探究

1、StringUtils.isNotBlank()和 StringUtils.isNotEmpty()的区别在于,前者把空格也当做字符串,后者会自动把字符串中的空格忽略,即第一个“ ”不为空为真,后...
  • bestcxx
  • bestcxx
  • 2017-03-01 20:30:25
  • 1301
    个人资料
    持之以恒
    等级:
    访问量: 6万+
    积分: 2492
    排名: 1万+
    爱是与世界平行
    最新评论