货币双值的舍入不正确

时间:2014-04-17 15:48:51

标签: java double bigdecimal

我的应用内部有一些计算问题。 它基本上是某种购物清单应用程序。 用户输入数量和价格。 该列表中可能有多达150种产品,但通常平均为20种产品。

我使用JTextFields,将StringsArrays中取出并放入10 * 27.10 10 * 27.81 Total: 549.08 。然后我解析Double并进行计算。 问题是我有时从我的数据库中的用户那里得到一个总数,当我验证它的错误时,例如(我发现有错误的最短列表):

549.08

显然,总数不是549.1而是Double totaltest=0; for (int j = 0; j < allcant.size(); j++) { cant[j] = allcant.get(j).getText().toString(); pret[j] = allpret.get(j).getText().toString(); Double temp = Double.parseDouble(cant[j]) * Double.parseDouble(pret[j]); totaltest = totaltest + temp; }

现在,我知道我的计算方法并不是最好的,几个月前,当我对Java知之甚少时,我就这样做了,因为它完成了这项工作后我就这么做了,我不知道计算非常复杂。所以我没有移动到BigDecimal,因为我做了很多计算,而且从我读过的内容来看,它比双重浮动要快得多。

无论如何,这是我的方法:

{{1}}

问题可能来自这里吗?或者我应该在代码中的其他位置查看? 我最有可能改变我的计算方式,但是我想知道最好的方法是什么,如果我在这里犯了错误。 我现在知道浮点数和东西,但奇怪的是它在我尝试复制时给出了正确的总数。

4 个答案:

答案 0 :(得分:3)

浮动和双重设计是不精确的。你永远不应该用这些来代表货币。而是使用int或long并以美分表示您的金额。例如,1.00内部为100。

答案 1 :(得分:1)

我试图重现你的算术,并得到了549.09999999999990905052982270717620849609375。如果四舍五入到小数点后两位显示,那么它将是549.10,所以我不认为你的问题是浮点精度,尽管我同意BigDecimal对于这个应用程序来说是更好的选择。

(我只在我的程序中使用BigDecimal来获得结果的准确打印输出。)

这是我的计划。我建议你弄清楚你的算术有什么不同,并研究一下。

import java.math.BigDecimal;

public class Test {
  public static void main(String[] args) {
    String[] cant = {"10", "10"};
    String[] pret = {"27.10", "27.81"};
    double totaltest=0;
    for (int j = 0; j < cant.length; j++) {
       Double temp = Double.parseDouble(cant[j]) * Double.parseDouble(pret[j]);
       totaltest = totaltest + temp;
    }
    System.out.println(new BigDecimal(totaltest));
  }
}

答案 2 :(得分:0)

为了获得正确的精度,请使用BigDecimal。

答案 3 :(得分:0)

前段时间我找到了这个问题的解决方案,忘了回来。对我来说这是一个错误。 用户应用程序正在某处进行微积分,将其发送到数据库然后我正在提取它并在另一个应用程序中重做微积分(使用相同的微积分方法)。

问题在于,当我创建数据库时,“客户端”告诉我价格永远不会超过2位小数,因此我将价格字段声明为十进制(10,2),因为我问了并确定了没关系。 然后,他们将价格定为0.305。用户应用程序将执行微积分,例如24 * 0.305 = 7.32,并且在数据库中它将记录为0.30,因为它只能接受2位小数,然后,当我从数据库中获取数据并在其他应用程序中重新编写时,当然,24 * 0.30 = 7.2

抱歉引导你走错了路。 现在一切都好。我了解到你永远不要相信用户/客户,总是仔细检查我猜,嘿。 有一个好的!