概述
很多人都知道在Java高精度计算时需要使用BigDecimal,实际上,很多对数值精度敏感的领域,比如结算、财务,也确实都是使用BigDecimal这种高精度计算工具来实现的,在二进制计算机的世界了,在有限的存储介质上无法准确保存0.1,就像十进制无法准确保存1/3类似,如果研究的更理论一些,可以看一下IEEE754二进制浮点数算术标准(https://baike.sogou.com/v514046.htm?fromTitle=IEEE+754),下面我们来看一个BigDecimal支持高精度计算的示例。
示例中BigDecimal的除法将1/3的结果小数点后保留了10000位,而这是float和double无法做到的,在使用BigDecimal的时候推荐使用字符串表达式作为入参创建示例,否则会出现上面示例的情况,超过一定位数后有误差。接下来我们简单分析下java.math.BigDecimal这个类。
1.数据结构,BigDecimal内部主要使用intVal、scale、intCompact来记录数值,类图如下:
对于scale这个实例变量,有必要说明一下,它表示的是缩放因子,并不是指精度,precision才是指精度,对于0.3这样一个数值,精度是1(从左到右第一个非0数开始统计的所有数字个数),而scale是可以变动的(甚至可以是负数),scale=1,则unscaledValue=3;scale=2,则unscaledValue=30,即数值=unscaledValue × 10^(-scal)。如果unscaledValue用long可以表示,则存储在intCompact中,如果超出long的范围,则存储在intVal中,我们可以单步调试加深一下印象。
2.对于BigDecimal的除法运算,推荐指定scale。比如文章开头的示例,1/3这样的运算,如果不指定scale,BigDecimal最终会抛异常,因为它会进行循环的除法运算。而指定了scale,BigDecimal就可以在一定的条件下终止循环除运算,从而计算出unscaledValue,就如上面对scale的解释类似,如果scale=1,那么unscaledValue=3,如果scale=3,那么unscaledValue=333,有兴趣的同学而已单步调试看看BigDecimal的除法运算逻辑。
最后
以上就是舒心糖豆为你收集整理的BigDecimal为什么能做到高精度计算的全部内容,希望文章能够帮你解决BigDecimal为什么能做到高精度计算所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复