bigdecimal加减乘除运算保留两位小数,bigdecimal强制保留2位小数

  bigdecimal加减乘除运算保留两位小数,bigdecimal强制保留2位小数

  00-1010 BigDecimal除法运算后保留两位小数。BigDecimal除法异常的详细描述。无终止十进制扩展异常的分析与解决。思考和总结

  

目录

BigDecimal numBigDecimal=new BigDecimal(5.33);numBigDecimal=convert number(numBigDecimal,3,2);//调用,5.33/3之后保留两位小数1.776666=1.78//BigDecimal截取小数位,四舍五入公共BigDecimal转换数(BigDecimal BigDecimal,Int Divnum,Intnum) {Double A=BigDecimal。double value();a=a/div num;String numString=0 ;for(int I=0;inumI){ numString= 0 ;} decimal format df=new decimal format(numString);返回新的BigDecimal(df.format(a)。toString());}当bigdecimal不能划分所有小数位(循环小数位)时,会报错。以上是解决方案,以下是BigDecimal和Divide方法提供的精确小数方法(推荐)

 

  @ Test public void Testa(){ String current lat 2= 2.455675 ;BigDecimal b=new BigDecimal(current lat 2);b=b.divide(new BigDecimal(3),2,BigDecimal。ROUND _ HALF _ UP);system . out . println(b);}//输出为0.82 bigdecimal . set scale();//用于格式化小数点set scale(1);//表示保留为小数,默认取整方式为set scale (1,bigdecimal . round _ down);//直接删除多余的小数位。比如2.35会变成2.3的set scale (1,bigdecimal . round _ up);//进位处理,2.35变成2.4 setscale (1,bigdecimal . round _ half _ up);//Round,2.35变成2.4 setscaler (1,bigdecimal . Round _ half _ down);//四舍五入,2.35变成2.3,如果是5,就向下舍入。

  

BigDecimal除法后保留两位小数

1、ROUND_UP

 

  远离零的舍入模式。在丢弃非零部分之前,总是增加数字(总是在非零丢弃部分之前的数字上加1)。请注意,这种舍入模式不会减小计算值的大小。2、ROUND_DOWN

  接近零的舍入模式。在丢弃一个部分之前,千万不要增加数字(千万不要在丢弃部分前面的数字上加1,即截断它)。请注意,这种舍入模式不会增加计算值的大小。3、ROUND_CEILING

  接近正无穷大的舍入模式。如果BigDecimal为正,舍入行为与ROUND_UP相同;如果为负值,舍入行为与ROUND_DOWN相同。请注意,这种舍入模式不会减少计算值。4、ROUND_FLOOR

  接近负无穷大的舍入模式。如果BigDecimal为正,舍入行为与ROUND_DOWN相同;如果为负值,舍入行为与ROUND_UP相同。请注意,这种舍入模式不会增加计算值。5、ROUND_HALF_UP

  四舍五入到“最近”的数,如果两个相邻数的距离相等,则为上舍入的舍入方式。如果丢弃部分=0.5,舍入行为与ROUND_UP相同;否则,舍入行为与ROUND_DOWN相同。注意,这是我们大多数人在小学学过的舍入模式(rounding)。6、ROUND_HALF_DOWN

  四舍五入到“最接近”的数字。如果两个相邻数的距离相等,则为向上取整的取整方式。如果舍弃0.5部分,取整行为与ROUND_UP相同;否则,舍入行为与ROUND_DOWN(五到六)相同。7、RO

  UND_HALF_EVEN

  向最接近的数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。此舍入模式也称为银行家舍入法,主要在美国使用。四舍六入,五分两种情况。如果前一位为奇数,则入位,否则舍去。以下例子为保留小数点1位,那么这种舍入方式下的结果。1.15>1.2 1.25>1.28、ROUND_UNNECESSARY

  断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。直接用数字转换为BigDecimal时会出现不精确的数值:

  

BigDecimal  e   =   new   BigDecimal(2.2);         System.out.println("e:"+e);          BigDecimal  f   =   new   BigDecimal(3.32);         System.out.println("f:"+f);          System.out.println("e+f="+e.add(f));               /*        e:2.20000000000000017763568394002504646778106689453125        f:3.319999999999999840127884453977458178997039794921875        e+f=5.520000000000000017763568394002504646778106689453125         */数字转换为字符串后再转换为BigDecimal时后计算则是精确的数值(所以先转换为字符串后再转BigDecimal会得到精确的结果):BigDecimal  e   =   new   BigDecimal("2.2");         System.out.println("e:"+e);          BigDecimal  f   =   new   BigDecimal("3.32");         System.out.println("f:"+f);          System.out.println("e+f="+e.add(f));        /*  结果如下:        e:2.2        f:3.32        e+f=5.52         */

 

  

BigDecimal除法异常Non-terminating decimal expansion

 

  

异常分析

其实提示信息已经很明显了,出现了无限循环小数,无法返回bigdecimal的值,回顾一下项目中的代码方式:

 

  

return new BigDecimal(baseMonth).divide(new BigDecimal(workDay)).setScale(2, BigDecimal.ROUND_HALF_UP);

代码如上,使用baseMonth除以workDay,返回的值按照四舍五入的方式保留两位小数。但是还是出现了异常,原因就在于divide的调用方式。

 

  

 

  

解决措施

使用divide的重载方法:divide(BigDecimal divisor, int scale, int roundingMode)

 

  

return new BigDecimal(baseMonth).divide(new BigDecimal(workDay), 2, BigDecimal.ROUND_HALF_UP);

备注:小数点后的精确类型,可参考JDK源码,以下为简要的截图举例说明

 

  

 

  

 

  

思考

问题是解决了,但是我还在想我第一种方式,显然,我在编码的时候也想到了指定小数点保留以及精确方式,但是还是会出现异常,那Bigdecimal提供的setScale的方法是在什么场景下使用呢?

 

  我猜想当被除数除以除数结果为有限小数时,可以使用Bigdecimal的setScale方法,那来验证一下

  

public static void main(String[] args) { //有限小数 BigDecimal a = new BigDecimal("2"); BigDecimal b = new BigDecimal("100"); System.out.println(a.divide(b).setScale(2, RoundingMode.HALF_UP)); }

结果为:0.02

 

  当使用.setScale(3, RoundingMode.HALF_UP)时,则结果为0.020;

  可见,以上猜想是正确的,即当bigdecimal进行除法运算时,则会发生小数点溢出的情况,此时,可能会出现无限小数,抛出异常,建议使用divide(BigDecimal divisor, int scale, int roundingMode)方式进行除法运算。

  

 

  

总结

bigdecimal的乘法和除法都会导致小数点的溢出,建议指定位数和精确方式bigdecimal的.setScale方法,用于指定有限小数不建议使用float、double进行bigdecimal的构建,会导致精度的紊乱,建议采用int和string在java程序中的小数计算,比如银行交易额、支付金额等都使用的是bigdecimal类型以上为个人经验,希望能给大家一个参考,也希望大家多多支持盛行IT。

 

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: