2010-03-01 35 views
1

我有一个csv文件,其中的金额和数量字段存在于除首部和尾部的每个记录明细记录。预告片记录具有总计费用值,这是总额详细记录中乘以数量字段的总和。我需要检查拖车总费用值是否等于我的数量和数量字段的计算值。我在所有这些计算中使用双数据类型关于大十进制

在csv文件中,数量字段显示为“10.12”或“10”或“10.0”或“10.456”或“10.4555”或“-10.12”。金额也可以有正值或负值。

在csv文件

H,ABC .....

“d”,..., “1”, “12.23”

“d”,... .., “3”, “ - 13.334”

“d”,......, “2”, “12”

T,CSD,123,12.345

- -------------当Vali我有以下代码--------------------

   double detChargeCount =0; 

       //From csv file i am reading trailer records charge value 
       String totChargeValue = items[3].replaceAll("\"","").trim(); 

       if (null != totChargeValue && !totChargeValue.equals("")) { 
        detChargeCount = new Double(totChargeValue).doubleValue(); 

       if(detChargeCount==calChargeCount) 
        validflag=true; 

---------------- -------在阅读CSV文件我有下面的代码

   if (null != chargeQuan && !chargeQuan.equals("")) { 
         tmpChargeQuan=Long(chargeQuan).longValue(); 
        } 

       if (null != chargeAmount && !chargeAmount.equals("")) { 
         tmpChargeAmt=new Double(chargeAmount).doubleValue(); 
          calChargeCount=calChargeCount+(tmpChargeQuan*tmpChargeAmt); 
          } 

我已经声明的变量tmpChargeQuan,tmpChargeAmt,calChargeCount为双

当我搜索网页我才知道,双可能会出现财务计算问题,因此需要使用BIGDECIMAL。但我想知道这种情况适用于我的计算。在我的情况下,小数点后的金额值可以达到5或6位数字“我可以使用双数据类型进行这种计算吗?我正在使用它进行验证。如果我使用上面的代码使用双数乘法,会产生问题吗?

回答

4

我什么阿迪尔已经succintly回答,您可以适应这些数字为双数据类型扩展。问题的问题?当得到计算出的数字,他们将得到正确计算出答案是否定的 - 他们一般不会,如果你考虑与增量不是太大的问题,那就是,你在承担余地与否双价值相当于另一个双倍价值即但对于涉及确切数字的计算(例如货币计算),您必须使用BigDecimal等类型来保存这些值。

当你有这样的数字: 1.23445 为double,它可能看起来像1.23445 但它实际上可能是类似 1.234450000003400345543034

当您在数字如,执行多个计算通常这些额外的地方并不重要 - 但是,随着时间的推移,它们会产生不准确的结果。随着BigDecimal的,当数被指定为它的字符串表示,它这个数字 - 它不会遭受“几乎一样好”的问题双打做。

我更新这个答案,包括从BigDecimal的双重构造的一些注意事项,在这个address找到。

此构造方法的结果可能是 有些不可预测。有人可能会 认为编写新 的BigDecimal(0.1)在Java中创建一个 BigDecimal正好等于0.1 (1未测量的值,为1的比例),但它实际上等于 是 0.1000000000000000055511151231257827021181583404541015625。这是因为0.1不能 精确表示为双(或者, 对于这个问题,作为一个二进制分数任何有限长度的 )。因此,被在给 构造被传​​递的值 不是正好等于 0.1,虽然表面上。

String构造,另外 另一方面,是完全可以预见: 写入new BigDecimal(“0.1”)将创建一个 BigDecimal正好等于 0.1,正如人们所期望。因此,通常建议 字符串构造函数在 首选项中使用。

当Double必须用作BigDecimal的源 时,请注意这个 构造函数提供了精确的 转换;它不会给出与使用BigDecimal(String) 构造函数使用 Double.toString(double)方法和 将double转换为 字符串的结果相同的 结果。要获得该结果,请使用 static valueOf(double)方法。

+0

非常感谢 所以你的言论,即使我小数点后有4位数(低精度)。乘法时我可能会遇到错误。另外我注意到bigdecimal有一个setscale方法来设置小数点和舍入方法后的数字位数。在我的情况下,我不需要做任何舍入,因为我只对数值进行验证。此外,我的输入可能有时在小数点后有2或3或0个数字。 BigDecimal是否有默认舍入?我将按以下方式分配 BigDecimal aa = new BigDecimal(“11.2359”); – Arav 2010-03-01 04:37:37

+0

除非您已将该数字指定为double,否则没有对BigDecimal的默认舍入。你作为一个字符串输入的是你得到的。如果您的比例小于当前结果,setScale上的舍入模式肯定是必需的 - 假设您有6.35,并且您说setScale(1) - 根据您选择的舍入模式,它将使其达到6.3或6.4。 – MetroidFan2002 2010-03-01 14:17:10

+0

非常感谢。所以你说如果我把它放在字符串BigDecimal(“11.2359”)中,并用另一个BigDecimal(“12”)类型进行乘法运算,它将不会结果?如果我把它作为double BigDecimal(11.2359)给出它,当我进行乘法运算或其他操作时,它会执行什么样的默认舍入操作。 如果我想比较两个大数小数的值来查看它们是否相等,那么我需要获得doublevalue,然后检查它们吗? – Arav 2010-03-02 01:05:48

2

它不是大小的问题上,它恰好表达浮点数。How the BigDecimal Class Helps Java Get its arithmetic right

+0

感谢很多的链接。在BIGDECIMAL中什么是默认舍入。我不想要发生任何舍入,因为我在这里进行验证。合计每条记录的数量(数量*金额),最后检查总费用金额。如果匹配,我会将值添加到表格中。 – Arav 2010-03-01 02:15:58

+0

阅读文档不会造成伤害。 :)它会回答你所有关于舍入的问题: http://java.sun.com/j2se/1.5.0/docs/api/java/math/BigDecimal.html – Jay 2010-03-01 02:19:32