1

我有一个 csv 文件,其中除了标题和尾记录之外,每个详细记录中都存在数量和数量字段。拖车记录有一个总费用值,即数量的总和乘以明细记录中的金额字段。我需要检查拖车总费用值是否等于我计算的金额和数量字段的值。我对所有这些计算都使用双精度数据类型

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

在 .csv 文件中

哈,ABC……

"D",....,"1","12.23"

"D",.....,"3","-13.334"

"D",......,"2","12"

T,csd,123,12.345

------------------ 验证时我有以下代码------------ --------

              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 声明为 double

当我在网上搜索时,我知道 double 可能会给财务计算带来问题,因此需要使用 BIGDECIMAL。但我想知道这种情况是否适用于我的计算。在我的情况下,金额值在小数点后最多可以有 5 位或 6 位数字“我可以使用双精度数据类型进行此计算吗?我正在使用它进行验证。如果我将上述代码与使用双精度的乘法一起使用会产生问题吗?

4

2 回答 2

4

我将扩展 Adeel 已经简洁回答的内容。您可以将这些数字放入双数据类型。问题是当数字被计算出来时,它们会被正确计算吗?答案是否定的——他们不会。一般来说,如果你用 delta 来解释这个问题,那并不是什么大问题,也就是说,你可以假设一个 double 值是否等于另一个 double 值。但是对于涉及精确数字的计算,例如货币计算,您必须使用 BigDecimal 等类型来保存值。

当你有这个数字: 1.23445 作为双精度时,它可能看起来像 1.23445 但实际上可能像 1.234450000003400345543034

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

我正在更新此答案以包含来自 BigDecimal 的双重构造函数的一些注释,该地址位于此地址

此构造函数的结果可能有些不可预测。有人可能会假设用 Java 编写 new BigDecimal(0.1) 会创建一个正好等于 0.1 的 BigDecimal(未缩放的值 1,缩放为 1),但它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 不能完全表示为双精度数(或者,就此而言,不能表示为任何有限长度的二进制分数)。因此,传递给构造函数的值并不完全等于 0.1,尽管看起来如此。

另一方面,String 构造函数是完全可预测的:编写 new BigDecimal("0.1") 会创建一个正好等于 0.1 的 BigDecimal,正如人们所期望的那样。因此,一般建议优先使用 String 构造函数。

当必须将 double 用作 BigDecimal 的源时,请注意此构造函数提供了精确的转换;它与使用 Double.toString(double) 方法然后使用 BigDecimal(String) 构造函数将双精度转换为字符串的结果不同。要获得该结果,请使用静态 valueOf(double) 方法。

于 2010-03-01T02:14:49.913 回答
2

这不是大小的问题,而是准确表达浮点数的问题。BigDecimal 类如何帮助 Java 获得正确的算术

于 2010-03-01T01:38:19.790 回答