使用BigDecimal解决计算过程中出现的精度错误问题

为什么要使用BigDecimal:

请参考以下的运行程序:

1.使用0.1+0.2时 出现了如下的情况:

   这个是没有BigDecimal的情况 0.1 + 0.2 =0.30000000000000004。

产生这种错误的原因是:

因为计算机是二进制的,对于double,float类型的10进制数据,通常是无法使用二进制进行精确表示的,因此就会出现这种情况,在实际的生活应用中,我们的计算题程序中,金融业的程序中,是不允许出现这种情况的,所以要使用BigDecimal去处理这种问题。

对于BigDecimal的介绍:

BigDecial是一种用于处理十六位以上的数据的java.lang.math包里的API,浮点型数据double可以用于处理十六位的有效数据,需要对更大或者更小的数进行运算和处理。float和double只能能用来做科学计算或者是工程计算(因为会出现类似如上的问题)因为这是一种对象,一个数就是一个对象,因此我们不可以和普通的类型一样去加减乘除 + - * /这样去对数据进行计算,具体的实现需要通过调用它的方法去完成一系列的计算。

BigDecimal的构造方法:

BigDecimal(int) 
BigDecimal(double) //不建议使用
BigDecimal(long)
BigDecimal(String) //推荐使用‘

BigDecimal的方法描述:

add(Bigdecimal) 加法

subtract(BigDecimal) 减法

multiply(BigDecimal) 乘法 

devide(BigDecimal) 除法 当出现无法除尽的时候 就会报错 如下:ava.lang.ArithmeticException 因此要使用下面的方法:

devide(BigDecimal divisor, int scale, RoundingMode roundingMode)。

为什么说不建议使用BigDecimal方法:

因为这个方法无法做到精确 :

 

 运行得到的效果如下:

 

 可以看到无法精确的得到0.1这个数据 ?为什么呢?

1、参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。

2、另一方面,String 构造方法是完全可预知的:写入 newBigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用String构造方法

综上所述,使用BigDecimal可以解决计算过程中数据精度错误的问题。
posted @ 2021-09-14 21:36  王佳智  阅读(772)  评论(0)    收藏  举报