Java BigDecimal学习

文章详细介绍了Java中BigDecimal类在处理精确数值计算时如何避免精度损失,包括使用valueOf()方法和构造函数,以及ROUND_UP、ROUND_DOWN等8种不同的舍入模式的解释和示例。此外,还讨论了在进行除法运算时可能出现的ArithmeticException异常,分析了原因并提供了解决方案,即指定舍入模式进行除法运算。
摘要由CSDN通过智能技术生成

Java BigDecimal不损失精度的方法

1、调用valueOf()方法(推荐)
2、调用构造方法BigDecimal(String)

在这里插入图片描述

Java BigDecimal的几种舍入模式

1、UP(BigDecimal.ROUND_UP)

  • 向绝对值最大的方向舍入
  • 只要舍弃位非0即进位

2、DOWN(BigDecimal.ROUND_DOWN)

  • 向绝对值最小的方向输入
  • 所有的位都舍弃,不存在进位情况。

3、CEILING(BigDecimal.ROUND_CEILING)

  • 天花板数:正数变大,负数也是变大。即正得越多,负得越少。
  • 正数,只要舍弃位非0即进位,同UP。负数,所有的位都舍弃,不存在进位情况,同DOWN。
  • Math.round方法使用的即为此模式。

4、FLOOR(BigDecimal.ROUND_FLOOR)

  • 地板数:正数变小,负数也是变小。即正得越少,负得越多。
  • 正数,所有的位都舍弃,不存在进位情况,同DOWN。负数,只要舍弃位非0即进位,同UP。

5、HALF_UP(BigDecimal.ROUND_HALF_UP)

最近数字舍入(5舍)。经典的四舍五入,5是进位。

6、HALF_DOWN(BigDecimal.ROUND_HALF_DOWN)

最近数字舍入(5舍)。HALF_DOWN中5是舍弃不进位。

示例代码:

// 5.5 
// 舍弃位为5,舍弃位后的数字为0
BigDecimal sum = BigDecimal.valueOf(5.550).setScale(1,BigDecimal.ROUND_HALF_DOWN);
// 5.6 
// 舍弃位为5,舍弃位后的数字非0
BigDecimal sum = BigDecimal.valueOf(5.551).setScale(1,BigDecimal.ROUND_HALF_DOWN);
// 5.6
// 舍弃位为5,舍弃位后的数字非0
BigDecimal sum = BigDecimal.valueOf(5.55001).setScale(1,BigDecimal.ROUND_HALF_DOWN);
// -5.6
// 舍弃位为5,舍弃位后的数字非0
BigDecimal sum = BigDecimal.valueOf(-5.55001).setScale(1,BigDecimal.ROUND_HALF_DOWN);

7、HALF_EVEN(BigDecimal.ROUND_HALF_EVEN)

银行家算法。
四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。

8、UNNECESSARY(BigDecimal.ROUND_UNNECESSARY)

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

示例代码:

// 抛出ArithmeticException 只有1位小数时不会报错
BigDecimal sum = BigDecimal.valueOf(-5.81).setScale(1,BigDecimal.ROUND_UNNECESSARY);

参考链接

Java BigDecimal不同模式下的舍入操作举例汇总

输入给定数字,保留1位数的结果如下:

输入数字UPDOWNCEILINGFLOORHALF_UPHALF_DOWN
1.341.41.31.41.31.31.3
1.351.41.31.41.31.41.3
1.361.41.31.41.31.41.4
-1.34-1.4-1.3-1.3-1.4-1.3-1.3
-1.35-1.4-1.3-1.3-1.4-1.4-1.3
-1.351-1.4-1.3-1.3-1.4-1.4-1.4
-1.36-1.4-1.3-1.3-1.4-1.4-1.4

Java BigDecimal进行除法运算报异常

问题现象

执行下面的代码:

BigDecimal sum = new BigDecimal("777.77");
BigDecimal avg = sum.divide(new BigDecimal("15"));
System.out.println(avg);

报错:

Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
	at java.math.BigDecimal.divide(BigDecimal.java:1693)
	at com.chuenhung.Test.main(Test.java:9)

原因分析

BigDecimal进行除法运算时,准确的商可能是一个无限长的小数,如果此时没有指定舍入模式,就会报ArithmeticException。
上面的777.77除以15的结果是个无限循环小数,而没有指定舍入模式,所以报错。

解决方法

调divide(divisor, scale, roundingMode);方法,其中scale为保留位数,roundingMode为舍入模式。

// 示例
BigDecimal avg = sum.divide(new BigDecimal("15"),3,BigDecimal.ROUND_DOWN);

参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值