Java 货币双精度值的舍入不正确

Java 货币双精度值的舍入不正确,java,double,bigdecimal,Java,Double,Bigdecimal,我的应用程序中有一些计算问题。 它基本上是某种购物清单应用程序。 用户输入数量和价格。 该列表中可能有多达150种产品,但通常平均约为20种 我使用JTextFields,从中提取字符串并将其放入数组中,然后解析Double并进行计算。 问题是,有时我从数据库中的用户那里得到一个总数,当我验证它是错误的时,例如,我能找到的有错误的最短列表: 10 * 27.10 10 * 27.81 Total: 549.08 显然,总数不是549.08,而是549.1 现在,我知道我的计算方法不是最好的,我

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

我使用JTextFields,从中提取字符串并将其放入数组中,然后解析Double并进行计算。 问题是,有时我从数据库中的用户那里得到一个总数,当我验证它是错误的时,例如,我能找到的有错误的最短列表:

10 * 27.10
10 * 27.81
Total: 549.08
显然,总数不是549.08,而是549.1

现在,我知道我的计算方法不是最好的,我是在几个月前做的,当时我对Java知之甚少,我就这样离开了它,因为它完成了工作,我没有非常复杂的计算。所以我没有移动到BigDecimal,因为我做了很多计算,从我读到的,它比double和float慢很多

无论如何,我的方法是:

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;
}
这个问题能解决吗?还是应该在代码中查找其他地方? 我很可能会改变我的计算方式,但我想知道什么是最好的方法,如果我在这里犯了错误。
我现在知道了浮点数之类的东西,但奇怪的是,当我尝试复制它时,它给出了正确的总数。

浮点数和Double在设计上是不精确的。你不应该用这些来表示货币。相反,使用int或long并用美分表示您的金额。例如,1.00在内部为100

Float和Double在设计上是不精确的。你不应该用这些来表示货币。相反,使用int或long并用美分表示您的金额。例如,1.00在内部为100

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

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

我试图复制您的算术,结果是549.0999999999905052982270717620849609375。如果四舍五入到小数点后两位显示,它将是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));
  }
}

我试图复制你的算术,结果是549.099999999050529298270717620849609375。如果四舍五入到小数点后两位显示,它将是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位小数,因此我将价格字段声明为10,2位小数,因为我询问并确保它是正确的。 例如,他们将价格设定为0.305。用户应用程序将进行演算,例如24*0.305=7.32,在数据库中它将记录为0.30,因为它只能接受2个小数,然后,当我从数据库中获取数据并在我的其他应用程序中重拨时,当然是24*0.30=7.2

很抱歉把你引向错误的道路。 现在一切都好了。我明白了,你永远不应该信任用户/客户,我想你应该反复检查,呵呵。
祝你过得愉快

我不久前找到了这个问题的解决方案,但忘了回来。这是我的一个错误,有点。 用户应用程序在某处进行演算,将其发送到数据库,然后我提取它,并在另一个应用程序中使用相同的演算方法重新进行演算

问题是,当我建立数据库时,客户告诉我价格永远不会超过2位小数,因此我将价格字段声明为10,2位小数,因为我询问并确保它是正确的。 例如,他们将价格设定为0.305。用户应用程序将进行演算,例如24*0.305=7.32,在数据库中它将记录为0.30,因为它只能接受2个小数,然后,当我从数据库中获取数据并在我的其他应用程序中重拨时,当然是24*0.30=7.2

很抱歉把你引向错误的道路。 现在一切都好了。我明白了,你永远不应该信任用户/客户,我想你应该反复检查,呵呵。
祝你过得愉快

使用BigDecimal而不是Double。在你的小应用程序中,你不会觉得performan和
大十进制和双精度的ce;进一步说明:货币通常最好存储在整数值中,即总美分/便士/任何东西。这避免了任何令人讨厌的浮点错误。我已经做了一些研究,知道你们用BigDecimal或long加美分、浮点和其他一些东西告诉我的所有事情,但是我使用的方法会导致这样的错误吗?为什么我不能复制它?这让我相信问题出在其他地方。我不想做一个新的计算方法,结果却发现问题出在别的地方。谢谢你的时间!在四舍五入到美分后,你很可能会得到正确的答案,但这不是一个好的做法。此外,不同的实现做不同的事情。例如,在浏览器中尝试javascript:alert2.0-1.1。即使是这样一个简单的计算,在javascript中也会产生轻微的错误。java中的10*27.10+10*27.81=549.10。通常情况下,float和double将被禁用,但使用非常非常小的数字,如.0000000000001。请使用BigDecimal而不是double。在你的小应用程序中,你不会觉得BigDecimal和Double的性能有什么不同;进一步说明:货币通常最好存储在整数值中,即总美分/便士/任何东西。这避免了任何令人讨厌的浮点错误。我已经做了一些研究,知道你们用BigDecimal或long加美分、浮点和其他一些东西告诉我的所有事情,但是我使用的方法会导致这样的错误吗?为什么我不能复制它?这让我相信问题出在其他地方。我不想做一个新的计算方法,结果却发现问题出在别的地方。谢谢你的时间!在四舍五入到美分后,你很可能会得到正确的答案,但这不是一个好的做法。此外,不同的实现做不同的事情。例如,在浏览器中尝试javascript:alert2.0-1.1。即使是这样一个简单的计算,在javascript中也会产生轻微的错误。java中的10*27.10+10*27.81=549.10。一般来说,float和double都是关闭的,但是使用非常非常小的数字,比如.0000000000001。谢谢您的回答!我知道这一点,但这是否会导致与如此短的计算有如此大的差异?我认为最大的问题不在这里,而是在我的代码中的其他地方,这就是我为什么要问的原因。再次感谢!谢谢你的回答!我知道这一点,但这是否会导致与如此短的计算有如此大的差异?我认为最大的问题不在这里,而是在我的代码中的其他地方,这就是我为什么要问的原因。再次感谢!再说一次,我知道这件事!我并不吝啬,谢谢你的时间,但是我已经写了好几次关于知道这一点的文章了!我想知道的是,使用double是否会导致如此大的差异。我的意思是,对于两种产品,它的误差为0.02。这不是很多吗,即使是双份的?再说一次,我知道这件事!我并不吝啬,谢谢你的时间,但是我已经写了好几次关于知道这一点的文章了!我想知道的是,使用double是否会导致如此大的差异。我的意思是,对于两种产品,它的误差为0.02。这不是很多吗,即使是双份的?