关于BigDecimal的使用
为什么使用BigDecimal
使用BigDecimal首先要注意到float,double是无法支持商业计算的。只能支持工程计算。即误差允许的计算。通常float占用4个字节,32位。double占用8个字节,64位。
float f=1.1f;
double d=1.1; //1.1d的d可以省略,平时用的最多的也是double。但是一旦涉及到计算的时候,问题出现
float f=1.1; //会警告精度有损失。因为是将double赋给了float,精度范围变小
System.out.println(5.1+1.1);//输出并不是6.2,而是6.19999999999999999. 如果经过循环计算误差就会逐渐放大。
推荐的办法就是计算的过程使用BigDecimal,BigDecimal是支持超大小数,同时支持精确计算。Java中的简单浮点数类型float和double不能够进行运算。不光是Java,在其它很多编程语言中也有这样的问题。这个问题相当严重,如果你有9.999999999999元,你的计算机是不会认为你可以购买10元的商品的。
在有的编程语言中提供了专门的货币类型来处理这种情况
Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances nonwithstanding.
The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one.
原来我们如果需要精确计算,非要用String来够造BigDecimal不可!在《Effective Java》一书中的例子是用String来够造BigDecimal的,但是书上却没有强调这一点,这也许是一个小小的失误吧。 现在我们已经可以解决这个问题了,原则是使用BigDecimal并且一定要用String来够造。
BigDecimal bd=new BigDecimal("5.1");
System.out.println(bd);//值输出仍然是5.1,这是下一步利用BigDeciaml进行商业计算的基础。
有些第三方的类,比如普元在excel导入时,最终赋给BigDecimal失去精度的值。
估计是直接利用new BigDecimal(double value)赋给类的BigDecimal属性。
解决的办法是不使用Double构造BigDecimal,而直接使用Double。Double可以在导入或读取时使用,到了计算的时候,可以使用BigDecimal。
如果是自己写Excel导入肯定会避免这样的问题,即使使用BigDecimal也没有问题。