公司新来一个同事,把BigDecimal运用的炉火纯青!字符串paramreturnintegertostringcompareto

Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理。

一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用Float和Double处理,但是Double.valueOf(String)和Float.valueOf(String)会丢失精度。所以开发中,如果我们需要精确计算的结果,则必须使用BigDecimal类来操作。

BigDecimal所创建的是对象,故我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

二、BigDecimal常用构造函数2.1、常用构造函数

BigDecimal(int)

创建一个具有参数所指定整数值的对象

BigDecimal(double)

创建一个具有参数所指定双精度值的对象

BigDecimal(long)

创建一个具有参数所指定长整数值的对象

BigDecimal(String)

创建一个具有参数所指定以字符串表示的数值的对象

2.2、使用问题分析

使用示例:

BigDecimala=newBigDecimal(0.1);System.out.println("avaluesis:"+a);System.out.println("=====================");BigDecimalb=newBigDecimal("0.1");System.out.println("bvaluesis:"+b);

结果示例:

avaluesis:0.1000000000000000055511151231257827021181583404541015625=====================bvaluesis:0.1

原因分析:

1)参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于0.1(非标度值1,其标度为1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于0.1(虽然表面上等于该值)。

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

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

三、BigDecimal常用方法详解3.1、常用方法

add(BigDecimal)

BigDecimal对象中的值相加,返回BigDecimal对象

subtract(BigDecimal)

BigDecimal对象中的值相减,返回BigDecimal对象

multiply(BigDecimal)

BigDecimal对象中的值相乘,返回BigDecimal对象

divide(BigDecimal)

BigDecimal对象中的值相除,返回BigDecimal对象

toString()

将BigDecimal对象中的值转换成字符串

doubleValue()

将BigDecimal对象中的值转换成双精度数

floatValue()

将BigDecimal对象中的值转换成单精度数

longValue()

将BigDecimal对象中的值转换成长整数

intValue()

将BigDecimal对象中的值转换成整数。

3.2、BigDecimal大小比较

java中对BigDecimal比较大小一般用的是bigdemical的compareTo方法

inta=bigdemical.compareTo(bigdemical2)

返回结果分析:

a=-1,表示bigdemical小于bigdemical2;a=0,表示bigdemical等于bigdemical2;a=1,表示bigdemical大于bigdemical2;

举例:a大于等于b

newbigdemica(a).compareTo(newbigdemical(b))>=0

四、BigDecimal格式化

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

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

NumberFormatcurrency=NumberFormat.getCurrencyInstance();//建立货币格式化引用NumberFormatpercent=NumberFormat.getPercentInstance();//建立百分比格式化引用percent.setMaximumFractionDigits(3);//百分比小数点最多3位

BigDecimalloanAmount=newBigDecimal("15000.48");//贷款金额BigDecimalinterestRate=newBigDecimal("0.008");//利率BigDecimalinterest=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格式化保留2为小数,不足则补0:

publicclassNumberFormat{

publicstaticvoidmain(String[]s){System.out.println(formatToNumber(newBigDecimal("3.435")));System.out.println(formatToNumber(newBigDecimal(0)));System.out.println(formatToNumber(newBigDecimal("0.00")));System.out.println(formatToNumber(newBigDecimal("0.001")));System.out.println(formatToNumber(newBigDecimal("0.006")));System.out.println(formatToNumber(newBigDecimal("0.206")));}/***@desc1.0~1之间的BigDecimal小数,格式化后失去前面的0,则前面直接加上0。*2.传入的参数等于0,则直接返回字符串"0.00"*3.大于1的小数,直接格式化返回字符串*@paramobj传入的小数*@return*/publicstaticStringformatToNumber(BigDecimalobj){DecimalFormatdf=newDecimalFormat("#.00");if(obj.compareTo(BigDecimal.ZERO)==0){return"0.00";}elseif(obj.compareTo(BigDecimal.ZERO)>0&&obj.compareTo(newBigDecimal(1))<0){return"0"+df.format(obj).toString();}else{returndf.format(obj).toString();}}}

结果为:

3.440.000.000.000.010.21

五、BigDecimal常见异常5.1、除法的时候出现异常

java.lang.ArithmeticException:Non-terminatingdecimalexpansion;noexactrepresentabledecimalresult

通过BigDecimal的divide方法进行除法时当不整除,出现无限循环小数时,就会抛异常:java.lang.ArithmeticException:Non-terminatingdecimalexpansion;noexactrepresentabledecimalresult.

解决方法:

divide方法设置精确的小数点,如:divide(xxxxx,2)六、BigDecimal总结6.1、总结

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

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

6.2、工具类推荐

packagecom.vivo.ars.util;importjava.math.BigDecimal;

/***用于高精确处理常用的数学运算*/publicclassArithmeticUtils{//默认除法运算精度privatestaticfinalintDEF_DIV_SCALE=10;

/***提供精确的加法运算**@paramv1被加数*@paramv2加数*@return两个参数的和*/

publicstaticdoubleadd(doublev1,doublev2){BigDecimalb1=newBigDecimal(Double.toString(v1));BigDecimalb2=newBigDecimal(Double.toString(v2));returnb1.add(b2).doubleValue();}

/***提供精确的加法运算**@paramv1被加数*@paramv2加数*@return两个参数的和*/publicstaticBigDecimaladd(Stringv1,Stringv2){BigDecimalb1=newBigDecimal(v1);BigDecimalb2=newBigDecimal(v2);returnb1.add(b2);}

/***提供精确的加法运算**@paramv1被加数*@paramv2加数*@paramscale保留scale位小数*@return两个参数的和*/publicstaticStringadd(Stringv1,Stringv2,intscale){if(scale<0){thrownewIllegalArgumentException("Thescalemustbeapositiveintegerorzero");}BigDecimalb1=newBigDecimal(v1);BigDecimalb2=newBigDecimal(v2);returnb1.add(b2).setScale(scale,BigDecimal.ROUND_HALF_UP).toString();}

/***提供精确的减法运算**@paramv1被减数*@paramv2减数*@return两个参数的差*/publicstaticdoublesub(doublev1,doublev2){BigDecimalb1=newBigDecimal(Double.toString(v1));BigDecimalb2=newBigDecimal(Double.toString(v2));returnb1.subtract(b2).doubleValue();}

/***提供精确的减法运算。**@paramv1被减数*@paramv2减数*@return两个参数的差*/publicstaticBigDecimalsub(Stringv1,Stringv2){BigDecimalb1=newBigDecimal(v1);BigDecimalb2=newBigDecimal(v2);returnb1.subtract(b2);}

/***提供精确的减法运算**@paramv1被减数*@paramv2减数*@paramscale保留scale位小数*@return两个参数的差*/publicstaticStringsub(Stringv1,Stringv2,intscale){if(scale<0){thrownewIllegalArgumentException("Thescalemustbeapositiveintegerorzero");}BigDecimalb1=newBigDecimal(v1);BigDecimalb2=newBigDecimal(v2);returnb1.subtract(b2).setScale(scale,BigDecimal.ROUND_HALF_UP).toString();}

/***提供精确的乘法运算**@paramv1被乘数*@paramv2乘数*@return两个参数的积*/publicstaticdoublemul(doublev1,doublev2){BigDecimalb1=newBigDecimal(Double.toString(v1));BigDecimalb2=newBigDecimal(Double.toString(v2));returnb1.multiply(b2).doubleValue();}

/***提供精确的乘法运算**@paramv1被乘数*@paramv2乘数*@return两个参数的积*/publicstaticBigDecimalmul(Stringv1,Stringv2){BigDecimalb1=newBigDecimal(v1);BigDecimalb2=newBigDecimal(v2);returnb1.multiply(b2);}

/***提供精确的乘法运算**@paramv1被乘数*@paramv2乘数*@paramscale保留scale位小数*@return两个参数的积*/publicstaticdoublemul(doublev1,doublev2,intscale){BigDecimalb1=newBigDecimal(Double.toString(v1));BigDecimalb2=newBigDecimal(Double.toString(v2));returnround(b1.multiply(b2).doubleValue(),scale);}

/***提供精确的乘法运算**@paramv1被乘数*@paramv2乘数*@paramscale保留scale位小数*@return两个参数的积*/publicstaticStringmul(Stringv1,Stringv2,intscale){if(scale<0){thrownewIllegalArgumentException("Thescalemustbeapositiveintegerorzero");}BigDecimalb1=newBigDecimal(v1);BigDecimalb2=newBigDecimal(v2);returnb1.multiply(b2).setScale(scale,BigDecimal.ROUND_HALF_UP).toString();}

/***提供(相对)精确的除法运算,当发生除不尽的情况时,精确到*小数点以后10位,以后的数字四舍五入**@paramv1被除数*@paramv2除数*@return两个参数的商*/

publicstaticdoublediv(doublev1,doublev2){returndiv(v1,v2,DEF_DIV_SCALE);}

/***提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指*定精度,以后的数字四舍五入**@paramv1被除数*@paramv2除数*@paramscale表示表示需要精确到小数点以后几位。*@return两个参数的商*/publicstaticdoublediv(doublev1,doublev2,intscale){if(scale<0){thrownewIllegalArgumentException("Thescalemustbeapositiveintegerorzero");}BigDecimalb1=newBigDecimal(Double.toString(v1));BigDecimalb2=newBigDecimal(Double.toString(v2));returnb1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();}

/***提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指*定精度,以后的数字四舍五入**@paramv1被除数*@paramv2除数*@paramscale表示需要精确到小数点以后几位*@return两个参数的商*/publicstaticStringdiv(Stringv1,Stringv2,intscale){if(scale<0){thrownewIllegalArgumentException("Thescalemustbeapositiveintegerorzero");}BigDecimalb1=newBigDecimal(v1);BigDecimalb2=newBigDecimal(v1);returnb1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).toString();}

/***提供精确的小数位四舍五入处理**@paramv需要四舍五入的数字*@paramscale小数点后保留几位*@return四舍五入后的结果*/publicstaticdoubleround(doublev,intscale){if(scale<0){thrownewIllegalArgumentException("Thescalemustbeapositiveintegerorzero");}BigDecimalb=newBigDecimal(Double.toString(v));returnb.setScale(scale,BigDecimal.ROUND_HALF_UP).doubleValue();}

/***提供精确的小数位四舍五入处理**@paramv需要四舍五入的数字*@paramscale小数点后保留几位*@return四舍五入后的结果*/publicstaticStringround(Stringv,intscale){if(scale<0){thrownewIllegalArgumentException("Thescalemustbeapositiveintegerorzero");}BigDecimalb=newBigDecimal(v);returnb.setScale(scale,BigDecimal.ROUND_HALF_UP).toString();}

/***取余数**@paramv1被除数*@paramv2除数*@paramscale小数点后保留几位*@return余数*/publicstaticStringremainder(Stringv1,Stringv2,intscale){if(scale<0){thrownewIllegalArgumentException("Thescalemustbeapositiveintegerorzero");}BigDecimalb1=newBigDecimal(v1);BigDecimalb2=newBigDecimal(v2);returnb1.remainder(b2).setScale(scale,BigDecimal.ROUND_HALF_UP).toString();}

/***取余数BigDecimal**@paramv1被除数*@paramv2除数*@paramscale小数点后保留几位*@return余数*/publicstaticBigDecimalremainder(BigDecimalv1,BigDecimalv2,intscale){if(scale<0){thrownewIllegalArgumentException("Thescalemustbeapositiveintegerorzero");}returnv1.remainder(v2).setScale(scale,BigDecimal.ROUND_HALF_UP);}

/***比较大小**@paramv1被比较数*@paramv2比较数*@return如果v1大于v2则返回true否则false*/publicstaticbooleancompare(Stringv1,Stringv2){BigDecimalb1=newBigDecimal(v1);BigDecimalb2=newBigDecimal(v2);intbj=b1.compareTo(b2);booleanres;if(bj>0)res=true;elseres=false;returnres;}}

THE END
1.Java中bigdecimal转integer的方法是什么问答在Java中,可以使用intValue()方法将BigDecimal转换为Integer。示例代码如下: BigDecimal bigDecimal = new BigDecimal("10.5"); Integer integerValue = bigDecimal.intValue(); System.out.println("Integer Value: " + integerValue); 复制代码 请注意,使用intValue()方法将BigDecimal转换为Integer时,小数部分将被...https://www.yisu.com/ask/16562518.html
2.long类型转为integerpostgre sql 字符串转为integer类型 select cast(setting_value as integer) from ud_organization_setting. select cast('123123' as integer) from ud_organization_setting. 判断BigDecimal是否可以转为Integer或Double 一句话,BigDecimal转为字符串,匹配正则表达式,so easy; 不废话,代码: import java.math.BigDecimal...https://www.shuzhiduo.com/topic/long%E7%B1%BB%E5%9E%8B%E8%BD%AC%E4%B8%BAinteger/
3.自己平时长期积累的java资料可供大家学习注:Double, Float, Long 转成字串的方法大同小异。 4、如何将整数int转化为Integer Integer integer=new Integer(i) 5、如何将Integer转化为字符串String Integer integer=String() 6、如何将Integer转化为int int num=Integer.intValue() 7、如何将String转化为BigDecimal ...https://www.360doc.cn/article/77399670_1000420378.html
1....中大整数BigInteger和高精度浮点数BigDecimal的基本应用和注意事...BigInteger和BigDecimal类中都实现了基本的四则运算、模运算等(计算的时候要调用对应的方法,不能对对象直接用运算符号),返回值是运算结果(仍然是相应类型的对象,不是在原对象上直接操作的)。 BigIntegerbigInteger=BigInteger.ZERO;BigIntegersum1=bigInteger.add(BigInteger.ONE);BigIntegerdiff1=bigInteger.subtract(BigInteg...https://blog.csdn.net/2401_88859777/article/details/143664804
2.BigDecimal.DivideToIntegralValue方法(Java.Math)Microsoft...BigDecimal 的this / divisor整數部分。 屬性 RegisterAttribute 例外狀況 NullPointerException 如果 為 ,則為divisor == null。 ArithmeticException 如果 為 ,則為divisor == 0。 備註 的java.math.BigDecimal.divideToIntegralValue(java.math.BigDecimal)Java 檔。 https://docs.microsoft.com/zh-hk/dotnet/api/java.math.bigdecimal.dividetointegralvalue
3.javalong默认四舍五入吗kekenai的技术博客今日博主使用BigDecimal的时候,由于idea自动设置了项目jdk版本为jdk11,突然发现下述方式提示了过时 price.setScale (2,BigDecimal.ROUND_CEILING); 1. 因为以前学习时,一直使用的jdk1.8,且百度都是上面的方式,便查看了一下源码 二、分析 从jdk11的源码上看,该方法应该是在jdk9的时候,进行了过时处理 ...https://blog.51cto.com/u_13259/12493951
4.JavaBigDecimal转IntegerJava BigDecimal转Integer /** * Map里的数据,如果值为BigDecimal类型,转为Integer * @param maps * @return */publicstaticMapmapBigDecimalToInteger(Map maps){if(maps==null){returnmaps;}if(maps.isEmpty()){returnmaps;}for(Object key:maps.keySet()){Object value=maps.get(key);if(value instance...https://www.jianshu.com/p/3399a86e9640
5.Java实现intlongIntegerLong之间的相互转换javaBigDecimal numBigDecimal = new BigDecimal(numberInt); // 或 numBigDecimal = BigDecimal.valueOf(numberInt); long numberlong = numBigDecimal.longValue();二、Long <-> Integer1. Long转化为Integer(1)使用Long的api1 2 Long numberLong = new Long(1000L); Integer intNumber = numberLong.intValue();...https://www.jb51.net/program/295725gfg.htm
6.BigDecimal转换时行为不一致·Issue#IBY26·wenshao/...期待BigDecimal正转反转类型不变, 其他类型保持现有特性 可接受对所有的BigDecimal类型,序列化时默认输出至少一位小数, 与Integer区别开, 对其他类型保持不变 publicclassCustomerBigDecimalCodecextendsBigDecimalCodec{privatestatic DecimalFormatformat;publicCustomerBigDecimalCodec(){format= new DecimalFormat();format.setMini...https://gitee.com/wenshao/fastjson/issues/14
7.Java中BigDecimal比较大小的方法BigDecimal转换为Integer有时候数据库数据为BigDecimal,而我们需要的是Integer类型,则要将数据进行转换,以 变量num为例 》先将BigDecimal转换为String类型 String str=num.toString(); 》再将String类型转换为Integer类型 Integer integer=Integer.parseInt(str); 以上同适用于Object类型数据文章标签: Java 数据库 关键词: Java方法 Java BigD...https://developer.aliyun.com/article/1470483
8.Java中BigDecimal比较大小的方法BigDecimal转换为Integerif(sysPartner.getCurrentAdvanceMoney().compareTo(newBigDecimal("0.00"))==0 ) { msg="此用户当前预付款为0"; } 有时候数据库数据为BigDecimal,而我们需要的是Integer类型,则要将数据进行转换,以 变量num为例 》先将BigDecimal转换为String类型 String str=num.toString(); ...http://yjs.liiix.com/?article/1470483
9.BigDecimal转为int类型「建议收藏」腾讯云开发者社区BigDecimal转为int类型「建议收藏」 直接调用BigDecimal的intValue()方法 示例: BigDecimal a = new BigDecimal(“1.1”); int b = a.intValue(); BigDecimal运算方法: 版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有...https://cloud.tencent.com/developer/article/2167357
10.将BigDecimal转成字符串为科学计数法的踩坑记录目录BigDecimal转字符串为科学计数法踩坑场景解决案例演示BigDecimal变科学计数法 BigDecimal转字符串为科学计数法踩坑 场景 在开发工程中,在金额方面都会定义bigdecimal类型,当然有时候也需要将金额转成字符串。我们可能会很自然的写成 金额.toString()方法如: https://www.apispace.com/news/post/15351.html