关于整数类型处理货币以及BigDecimal类的使用

本文深入探讨了Java开发中货币处理的常见问题,特别是浮点数运算的不准确性,提出了使用BigDecimal类的解决方案。文章详细介绍了BigDecimal的构造方法、常用方法及除法舍入处理模式,旨在帮助开发者避免金额计算误差。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、货币处理问题

在java开发中经常涉及金额处理,但对于浮点数的运算时容易出现不准确的情况
一个简单的例子

System.out.println(10.00-9.60);

执行结果为
输出结果

针对金额运算或者小数运算可能出现的问题的解决方案

  1. 使用BigDecimal
    BigDecimal能很好的处理浮点数计算无法精确计算的问题,并且本身提供了加减乘除的常用数学算法。

  2. 使用整型
    把数额扩大100倍变为整型,这个方法有一定的局限,且金额最大只能到两千万(Integer最大值为2147483647,从分算起只能到千万元),适用性没有BigDecimal好

二、BigDecimal类的使用

1、注意事项

从jdk的API文档中得知,使用BigDecimal的构造方法BigDecimal(double val)的结果有一定的不可预知性(例如,new BigDecimal(0.1)所创建的BigDecimal实际上等于0.1000000000000000055511151231257827021181583404541015625),建议使用BigDecimal(String val)或者BigDecimal.valueOf(double val),这是将 float 或 double 转换为 BigDecimal 的首选方法,因为它不会遇到 BigDecimal(double) 构造方法的不可预知问题。

2、常用方法说明
  • 求绝对值abs(): 返回 BigDecimal,其值为此 BigDecimal 的绝对值,其标度为 this.scale()。

  • 加法运算add(BigDecimal augend): 返回一个 BigDecimal,其值为 (this + augend),其标度为 max(this.scale(), augend.scale())。

  • 减法运算subtract(BigDecimal subtrahend): 返回一个 BigDecimal,其值为 (this - subtrahend),其标度为 max(this.scale(), subtrahend.scale())。

  • 乘法运算multiply(BigDecimal multiplicand): 返回一个 BigDecimal,其值为 (this × multiplicand),其标度为 (this.scale() + multiplicand.scale())。

  • 除法运算divide(BigDecimal divisor, int scale, int roundingMode): 返回一个 BigDecimal,其值为 (this / divisor),其标度为指定标度,即保留小数点后多少位,舍入模式为指定舍入模式。

  • 指数运算pow(int n) : 返回其值为 (this^n) 的 BigDecimal,准确计算该幂,使其具有无限精度。

  • 求余运算remainder(BigDecimal divisor) : 返回其值为 (this % divisor) 的 BigDecimal。

  • 乘以10的指数运算scaleByPowerOfTen(int n) : 返回其数值等于 (this * 10^n) 的 BigDecimal。

  • 转化为BigInteger类toBigInteger() : 将此 BigDecimal 转换为 BigInteger。

  • 比较方法compareTo(BigDecimal val) : 将此 BigDecimal 与val进行比较,当此 BigDecimal 在数字上小于、等于或大于 val 时,返回 -1、0 或 1。建议使用以下语句执行上述比较:(x.compareTo(y) < op > 0),其中 < op > 是六个比较运算符(<, ==, >, >=, !=, <= )之一。

3、除法舍入处理模式
  • BigDecimal.ROUND_UP 远离零的舍入模式。在丢弃非零部分之前始终增加数字。最后一位如果大于0,则向前进一位,正负数都如此。
  • BigDecimal.ROUND_DOWN 接近零的舍入模式。在丢弃某部分之前始终不增加数字(即截短)。最后一位不管是什么都会被舍弃。
  • BigDecimal.ROUND_CEILING 如果是正数,按ROUND_UP处理,如果是负数,按照ROUND_DOWN处理。例如6.1->7; -7.1->-7;所以这种近似的结果都会>=实际值。
  • BigDecimal.ROUND_FLOOR 跟BigDecimal_ROUND_CEILING相反。例如6.1->6;-7.1->-8。这种处理的结果<=实际值。
  • BigDecimal.ROUND_HALF_DOWN 如果最后一位<=5则舍弃,如果>5, 向前进一位。如7.5->7;7.6->8;-7.5->-7
  • BigDecimal.ROUND_HALF_UP 即四舍五入。如果最后一位<5则舍弃,如果>=5, 向前进一位。反之舍弃。如7.5->8;7.4->7;-7.5->-8
  • BigDecimal.ROUND_HALF_EVEN 向“最接近的”数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。如果舍弃部分左边的数字为奇数,则舍入行为与 ROUND_HALF_UP 相同;如果为偶数,则舍入行为与 ROUND_HALF_DOWN 相同。注意,在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。如7.5->8;8.5->8;7.4->7;-7.5->-8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值