持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
在项目开发中,我们经常会涉及数字计算,尤其是金钱方面会涉及到浮点数的计算,但是由于计算机对于浮点数的存储规则的限制,使得float和double在计算过程中往往不能提供精确的计算结果。
println(1-(9 * 0.1))
上面这个运算结果本应该是0.1,但是最后输出的结果却并不精确,而是一个无限接近正确值得数据。
0.09999999999999998
一般在金钱计算的时候,我们会把运算的金额扩大100倍转化为int型,计算完成之后再缩小100倍,这样处理简单快捷。
除此之外,Java还提供了BigDecimal来做数据运算。
BigDecimal
BigDecimal是专门为了弥补浮点数无法精确计算而设计的类,它提供了常用的加减乘除等计算方法。
构造BigDecimal
BigDecimal
提供了很多构造方法,支持int,long,double等数据类型直接转化为BigDecimal
对象。
println(BigDecimal("0.01"))//String
println(BigDecimal(0.01))//double
不过虽然BigDecimal
提供了double的构造函数,但是并不推荐使用,先看上面的输出结果
0.01
0.01000000000000000020816681711721685132943093776702880859375
可以看到BigDecimal(double val)
构造器创建的结果数据并不精确,它具有一定的不可预知性,所以当我们需要将double
转化为BigDecimal
对象的时候,可以优先考虑BigDecimal(Stringg val)
构造器,除此之外,BigDecimal
还提供了BigDecimal.valueOf(0.01)
方法,它也可以精确地转换。
println(BigDecimal.valueOf(0.01))//输出0.01
运算
public BigDecimal add(BigDecimal augend)//加
public BigDecimal subtract(BigDecimal subtrahend)//减
public BigDecimal multiply(BigDecimal multiplicand)//乘
public BigDecimal divide(BigDecimal divisor)//除
public BigDecimal divide(BigDecimal divisor,int scale, int roundingMode)//除,保留几位小数和舍取模式
加,减 ,乘 运算比较简单,需要注意的是除法运算,一般情况下不推荐使用divide(BigDecimal divisor)
,因为除法可能出现除不尽的情况。
println(BigDecimal(1).divide(BigDecimal(3)))
这种情况下就会计算失败,抛出异常(Non-terminating decimal expansion; no exact representable decimal result.
),这时候就需要使用带有指定保留几位小数和舍取模式的除法方法。
println(BigDecimal(1).divide(BigDecimal(3), 2, RoundingMode.DOWN))//输出0.33
舍取模式是RoundingMode枚举类,常见的有ROUND_UP
(向远离零的方向舍入),ROUND_DOWN
(向接近零的方向舍入)
BigDecimal设计的目的是为了精确地表示大数和小数,它是不可变的,在每一步运算过程中都会生成新的对象,所以需要防止频繁使用它进行大量的数学运算,防止内存抖动。
今天的文章BigDecimal 使用分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/15374.html