关于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也没有问题。

 

 

 

 

 

 

 

posted @ 2014-04-24 09:38  highriver  阅读(1284)  评论(0编辑  收藏  举报