java divide 用法_Java关于BigDecimal的介绍及用法(二)

一、BigDecimal格式化

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

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

@Test

public voidtest8(){NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用

NumberFormat percent = NumberFormat.getPercentInstance(); //建立百分比格式化引用

percent.setMaximumFractionDigits(3); //百分比小数点最多3位

BigDecimal money = new BigDecimal("15000.48"); // 合同金额

BigDecimal taxRate = new BigDecimal("0.008"); // 税率

BigDecimal taxRateMoney = money.multiply(taxRate); // 利息

System.out.println("合同金额: " +currency.format(money));

System.out.println("税率: " +percent.format(taxRate));

System.out.println("利息: " +currency.format(taxRateMoney));

}

结果:

8a1d0dfa11d929d5584ee77a001766df.png

BigDecimal格式化保留2为小数,不足则补0:

@Test

public voidtest9(){

System.out.println(formatToNumber(new BigDecimal("3.435")));

System.out.println(formatToNumber(new BigDecimal(0)));

System.out.println(formatToNumber(new BigDecimal("0.00")));

System.out.println(formatToNumber(new BigDecimal("0.001")));

System.out.println(formatToNumber(new BigDecimal("0.006")));

System.out.println(formatToNumber(new BigDecimal("0.206")));

}

/**

* @desc 1.0~1之间的BigDecimal小数,格式化后失去前面的0,则前面直接加上0。

* 2.传入的参数等于0,则直接返回字符串"0.00"

* 3.大于1的小数,直接格式化返回字符串

* @param obj 传入的小数

* @return

*/

public staticString formatToNumber(BigDecimal obj) {

DecimalFormat df = new DecimalFormat("#.00");

if(obj.compareTo(BigDecimal.ZERO)==0) {

return "0.00";

}else if(obj.compareTo(BigDecimal.ZERO)>0&&obj.compareTo(new BigDecimal(1))<0){

return "0"+df.format(obj).toString();

}else{

returndf.format(obj).toString();

}

}

结果为:

6291b7ef278ae6f9d21cb1744a2f8be3.png

二、BigDecimal常见异常

2.1、除法divide() 出现异常

使用除法函数在divide的时候要设置各种参数,要有除数、精确的小数位数和舍入模式,不然会出现报错。源码如下:

注意这个BigDecimal的divide方法有两个重载的方法,一个是传两个参数的,一个是传三个参数的:

两个参数的方法:

@param divisor value by which this {@code BigDecimal} is to be divided. 传入除数

@param roundingMode rounding mode to apply. 传入round的模式

61e5f548e148f5d8f198a673e7da6a1b.png

三个参数的方法:

@param divisor value by which this {@code BigDecimal} is to be divided. 传入除数

@param scale scale of the {@code BigDecimal} quotient to be returned. 传入精度

@param roundingMode rounding mode to apply. 传入round的模式

a72ee8978b1d13ddab7ceb1d5153ab8a.png

代码演示:

@Test

public voidtest10(){

BigDecimal Dividend = new BigDecimal("1");

BigDecimal divisor = new BigDecimal("3");

BigDecimal res1 = Dividend.divide(divisor,3,BigDecimal.ROUND_UP);

System.out.println("除法ROUND_UP:"+res1);

BigDecimal res2 = Dividend.divide(divisor,3,BigDecimal.ROUND_DOWN);

System.out.println("除法ROUND_DOWN:"+res2);

BigDecimal res3 = Dividend.divide(divisor,3,BigDecimal.ROUND_CEILING);

System.out.println("除法ROUND_CEILING:"+res3);

BigDecimal res4 = Dividend.divide(divisor,3,BigDecimal.ROUND_FLOOR);

System.out.println("除法ROUND_FLOOR:"+res4);

BigDecimal res5 = Dividend.divide(divisor,3,BigDecimal.ROUND_HALF_UP);

System.out.println("除法ROUND_HALF_UP:"+res5);

BigDecimal res6 = Dividend.divide(divisor,3,BigDecimal.ROUND_HALF_DOWN);

System.out.println("除法ROUND_HALF_DOWN:"+res6);

BigDecimal res7 = Dividend.divide(divisor,3,BigDecimal.ROUND_HALF_EVEN);

System.out.println("除法ROUND_HALF_EVEN:"+res7);

BigDecimal res8 = Dividend.divide(divisor,3,BigDecimal.ROUND_UNNECESSARY);

System.out.println("除法ROUND_UNNECESSARY:"+res8);

}

结果展示:

ceaa70c29e5b3c0f48f139c4d2fb3e2a.png

86490758adc4472da2768e4919caba2a.png

原因分析:

断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。

2.2、除法divide() 出现异常

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

原因分析:

原来JAVA中如果用BigDecimal做除法的时候一定要在divide方法中传递第二个参数,定义精确到小数点后几位,否则在不整除的情况下,结果是无限循环小数时,就会抛出以下异常。java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

解决方法:

a.divide(b, 2, BigDecimal.ROUND_HALF_UP);

三、BigDecimal的八种舍入模式

@Test

public voidtest11(){

BigDecimal a = new BigDecimal("1.12345");

System.out.println("a = " +a);

BigDecimal b = a.setScale(4,BigDecimal.ROUND_HALF_DOWN);

System.out.println("b = " +b);

BigDecimal c = a.setScale(4,BigDecimal.ROUND_HALF_UP);

System.out.println("c = " +c);

}

4749a2fdb6f128e20d303ffa7620ff5e.png

7a3d277b348dde094caf3e84cbc94928.png

3.1、ROUND_UP

舍入远离零的舍入模式(向远离0的方向舍入)。

在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)。

注意,此舍入模式始终不会减少计算值的大小。

3.2、ROUND_DOWN

接近零的舍入模式(向零方向舍入)。

在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截短)。

注意,此舍入模式始终不会增加计算值的大小。

3.3、ROUND_CEILING

接近正无穷大的舍入模式(向正无穷方向舍入)。

如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同;

如果为负,则舍入行为与 ROUND_DOWN 相同。

注意,此舍入模式始终不会减少计算值。

3.4、ROUND_FLOOR

接近负无穷大的舍入模式(向负无穷方向舍入)。

如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;

如果为负,则舍入行为与 ROUND_UP 相同。

注意,此舍入模式始终不会增加计算值。

3.5、ROUND_HALF_UP

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为向上舍入的舍入模式(向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6)。

如果舍弃部分 >= 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同。

注意,这是我们大多数人在小学时就学过的舍入模式(四舍五入)。

3.6、ROUND_HALF_DOWN

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则为上舍入的舍入模式

(向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5)。

如果舍弃部分 > 0.5,则舍入行为与 ROUND_UP 相同;否则舍入行为与 ROUND_DOWN 相同(五舍六入)。

3.7、ROUND_HALF_EVEN

向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。

如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;

如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同

(向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP ,如果是偶数,使用ROUND_HALF_DOWN)。

注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。

此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况。

如果前一位为奇数,则入位,否则舍去。

以下例子为保留小数点1位,那么这种舍入方式下的结果。

1.15>1.2 1.25>1.2

3.8、ROUND_UNNECESSARY

断言请求的操作具有精确的结果,因此不需要舍入(计算结果是精确的,不需要舍入模式)。

如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。

四、BigDecimal总结

4.1、总结

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

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

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

4.2、工具类推荐

8f900a89c6347c561fdf2122f13be562.pngArithmeticUtils

五、请关注后续博客

记得点波收藏o!!!

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java BigDecimalJava中用于高精度计算的类。它允许我们进行任意精度的数字计算,而不会出现舍入误差。 在Java中,基本数据类型(如int、double等)的计算是有限制的。例如,double类型只能存储15位有效数字,而且在计算过程中可能会出现舍入误差。这在需要精确计算的场合下是不可接受的,这就需要使用BigDecimal类。 以下是一些Java BigDecimal的常用方法: 1. 实例化BigDecimal对象 可以使用BigDecimal的构造函数来实例化一个对象,例如: ``` BigDecimal num1 = new BigDecimal("1234.5678"); BigDecimal num2 = new BigDecimal(9876.5432); ``` 2. 加法、减法、乘法和除法 可以使用add()、subtract()、multiply()和divide()方法进行加、减、乘和除运算,例如: ``` BigDecimal result1 = num1.add(num2); BigDecimal result2 = num1.subtract(num2); BigDecimal result3 = num1.multiply(num2); BigDecimal result4 = num1.divide(num2, 2, RoundingMode.HALF_UP); // 保留两位小数 ``` 3. 取反、取绝对值、取反余弦等 可以使用negate()、abs()、acos()等方法进行相应的计算,例如: ``` BigDecimal result5 = num1.negate(); // 取反 BigDecimal result6 = num1.abs(); // 取绝对值 BigDecimal result7 = new BigDecimal(Math.PI).acos(); // 取反余弦 ``` 4. 比较大小 可以使用compareTo()方法进行大小比较,例如: ``` int cmp = num1.compareTo(num2); if (cmp > 0) { System.out.println("num1 > num2"); } else if (cmp < 0) { System.out.println("num1 < num2"); } else { System.out.println("num1 = num2"); } ``` 以上是Java BigDecimal的一些常用方法,使用BigDecimal类可以很方便地进行高精度计算。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值