Java BigDecimal使用及基本运算(推荐)
BigDecimal简介
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。
提起BigDecimal,相信大家都使用过,之所以总结这篇呢,是因为最近发现项目中使用的不是太规范,在某些场景下甚至出现代码抛出异常的情况,
所以就总结了这篇,希望大家在使用时,可以少踩一些坑。
1.基本运算
1.1加法
BigDecimalnumber1=newBigDecimal("88.88"); BigDecimalnumber2=newBigDecimal("11.12"); BigDecimalnumber3=number1.add(number2); System.out.println("number1addnumber2="+number3);
输出结果:
number1addnumber2=100.00
1.2减法
BigDecimalnumber1=newBigDecimal("88.88"); BigDecimalnumber2=newBigDecimal("11.12"); BigDecimalnumber3=number1.subtract(number2); System.out.println("number1subtractnumber2="+number3);
输出结果:
number1subtractnumber2=77.76
1.3乘法
BigDecimalnumber1=newBigDecimal("88.88"); BigDecimalnumber2=newBigDecimal("11.12"); BigDecimalnumber3=number1.multiply(number2); System.out.println("number1multiplynumber2="+number3);
输出结果:
number1multiplynumber2=988.3456
1.4除法
BigDecimalnumber1=newBigDecimal("88"); BigDecimalnumber2=newBigDecimal("11"); BigDecimalnumber3=number1.divide(number2); System.out.println("number1dividenumber2="+number3);
输出结果:
number1dividenumber2=8
因为上面2个数可以整除,所以这么用没有问题,不过一但不能被整除,这么用就会有潜在的风险,会抛出java.lang.ArithmeticException异常,所以强烈建议像下面这样使用:
BigDecimalnumber1=newBigDecimal("88.88"); BigDecimalnumber2=newBigDecimal("11.12"); BigDecimalnumber3=number1.divide(number2,2,RoundingMode.HALF_UP); System.out.println("number1dividenumber2="+number3);
输出结果:
number1dividenumber2=7.99
此时使用的divide()方法源码如下所示:
publicBigDecimaldivide(BigDecimaldivisor,intscale,RoundingModeroundingMode){ returndivide(divisor,scale,roundingMode.oldMode); }
这里的scale指的是要保留的小数位数,我们传的是2,即保留2位小数。
这里的roundingMode指的是舍入模式,我们这里传的是RoundingMode.HALF_UP,即经常使用的四舍五入模式。
1.5保留小数位数
如果我们想对BigDecimal类型保留小数位数,可以使用setScale()方法,使用方法如下所示:
BigDecimalnumber1=newBigDecimal("88.88"); BigDecimalnumber2=newBigDecimal("11.12"); BigDecimalnumber3=number1.multiply(number2); System.out.println("number1multiplynumber2="+number3); //保留3位小数,四舍五入 BigDecimalnumber4=number3.setScale(3,RoundingMode.HALF_UP); System.out.println("number3setScale="+number4);
输出结果:
number1multiplynumber2=988.3456
number3setScale=988.346
1.6比较大小
BigDecimal比较大小,可以使用compareTo()方法,使用方法如下所示:
BigDecimalnumber1=newBigDecimal("88.88"); BigDecimalnumber2=newBigDecimal("11.11"); BigDecimalnumber3=newBigDecimal("99.99"); BigDecimalnumber4=newBigDecimal("88.88"); System.out.println("number1compareTonumber2="+number1.compareTo(number2)); System.out.println("number1compareTonumber3="+number1.compareTo(number3)); System.out.println("number1compareTonumber4="+number1.compareTo(number4));
输出结果:
number1compareTonumber2=1
number1compareTonumber3=-1
number1compareTonumber4=0
由输出结果可以看出:
当number1小于number2时,返回-1,
当number1等于number2时,返回0,
当number1大于number2时,返回1。
2.踩坑总结
2.1NullPointerException异常
在使用BigDecimal类型进行计算时,比如上面提到的加、减、乘、除、比较大小时,一定要保证参与计算的两个值不能为空,否则会抛出java.lang.NullPointerException异常。
比如下面的2段代码,都会抛出异常:
BigDecimalnumber1=null; BigDecimalnumber2=newBigDecimal("11.12"); BigDecimalnumber3=number1.add(number2); System.out.println("number1addnumber2="+number3);
BigDecimalnumber1=newBigDecimal("88.88"); BigDecimalnumber2=null; BigDecimalnumber3=number1.add(number2); System.out.println("number1addnumber2="+number3);
抛出的异常如下图所示:
2.2ArithmeticException异常
一次在使用BigDecimal的divide方法时,抛出java.lang.ArithmeticException异常,错误代码如下所示:
//含税金额 BigDecimalinclusiveTaxAmount=newBigDecimal("1000"); //税率 BigDecimaltaxRate=newBigDecimal("0.13"); //不含税金额=含税金额/(1+税率) BigDecimalexclusiveTaxAmount=inclusiveTaxAmount.divide(BigDecimal.ONE.add(taxRate)); System.out.println(exclusiveTaxAmount);
运行时抛出以下异常:
java.lang.ArithmeticException:Non-terminatingdecimalexpansion;noexactrepresentabledecimalresult.
报错原因是因为无法整除,导致结果是无限循环小数:
解决方案是指定下舍入模式,比如我们最常用的四舍五入模式:
//不含税金额=含税金额/(1+税率) BigDecimalexclusiveTaxAmount=inclusiveTaxAmount.divide(BigDecimal.ONE.add(taxRate),RoundingMode.HALF_UP);
此时不再报错,输出结果为:
885
但这里我的需求是保留2位小数,四舍五入,因此代码应该是下面这样的:
//不含税金额=含税金额/(1+税率) BigDecimalexclusiveTaxAmount=inclusiveTaxAmount.divide(BigDecimal.ONE.add(taxRate),2,RoundingMode.HALF_UP);
此时的输出结果为:
884.96
如果你的IDEA装了阿里巴巴代码规范插件,如果不指定RoundingMode,会有下面这样的提示:
3.使用规范
尽量不要在项目中使用newBigDecimal("0"),而是使用BigDecimal提供的常量BigDecimal.ZERO。
BigDecimalzero=BigDecimal.ZERO; BigDecimalone=BigDecimal.ONE; BigDecimalten=BigDecimal.TEN;
总结
到此这篇关于JavaBigDecimal使用指南针(推荐)的文章就介绍到这了,更多相关JavaBigDecimal使用内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。