Java 为什么我会失去大十进制精度?
我正在从txt转换数字,如5.326.236,56 money,并首先删除点和逗号,但我丢失了小数,我已经将列定义为:Java 为什么我会失去大十进制精度?,java,hibernate,Java,Hibernate,我正在从txt转换数字,如5.326.236,56 money,并首先删除点和逗号,但我丢失了小数,我已经将列定义为: @Column(name = "total", precision = 16, scale = 2) private BigDecimal total; 但我丢失了小数点后的最后两位数 这是我的密码: private BigDecimal parseBigLong(String stringNumber) { String cvalue = ""; for (
@Column(name = "total", precision = 16, scale = 2)
private BigDecimal total;
但我丢失了小数点后的最后两位数
这是我的密码:
private BigDecimal parseBigLong(String stringNumber) {
String cvalue = "";
for (int n = 0; n < stringNumber.length(); n++) {
char c = stringNumber.charAt(n);
if (!(".").equals(String.valueOf(c))) {
if (!(",").equals(String.valueOf(c))) {
if (!("-").equals(String.valueOf(c))) {
cvalue = cvalue + c;
}
}
}
}
BigDecimal bigDecimal = ( BigDecimal.valueOf(Long.parseLong(cvalue) / 100));
return bigDecimal;
}
基本上,在构造BigDecimal之前很久,您就在上进行整数除法 当然,整数除法会产生另一个长。。。它不能表示小数点后的两位数字 可以通过使用BigDecimal进行除法来避免这种情况: 或者,如果不需要强制cvalue是有效的整数长表示形式的约束:
BigDecimal bigDecimal = (new BigDecimal(cvalue))
.divide(new BigDecimal(100));
也许有更好的办法。DecimalFormat类理解各种本地化的数字格式。如果您创建一个合适的格式,然后调用setParseBigDecimaltrue,那么该格式的解析方法将生成一个BigDecimal。。。直接地不需要任何字符串攻击来消除逗号和句点字符。您不需要假设输入的数字正好在小数点后两位。基本上,在构造BigDecimal之前,您正在对长进行整数除法 当然,整数除法会产生另一个长。。。它不能表示小数点后的两位数字 可以通过使用BigDecimal进行除法来避免这种情况: 或者,如果不需要强制cvalue是有效的整数长表示形式的约束:
BigDecimal bigDecimal = (new BigDecimal(cvalue))
.divide(new BigDecimal(100));
也许有更好的办法。DecimalFormat类理解各种本地化的数字格式。如果您创建一个合适的格式,然后调用setParseBigDecimaltrue,那么该格式的解析方法将生成一个BigDecimal。。。直接地不需要任何字符串攻击来消除逗号和句点字符。您不需要假设输入的数字正好在小数点后两位。首先,您的转换逻辑很奇怪: 你正在撕掉所有的-,和。在构造BigDecimal时,假设它是2位小数 这意味着,如果给您一个字符串1234.5678,那么您将构建123456.78作为结果 根据您的意图,以下是答案: 如果要根据输入字符串中的值转换为BigDecimal 这意味着,如果希望字符串1234.5678在BigDecimal中变成1234.5678,可以使用DecimalFormat,如本问题所述: 如果奇怪的逻辑是你想要做的 这意味着,如果希望字符串1234.5678在BigDecimal中变为123456.78,那么代码中的具体问题是要进行长除法,并使用结果构造BigDecimal 在Java和许多其他语言中,整数与整数的除法得到的结果是整数,所以123456/100得到的结果是1234 你想要达到的目标可以通过
BigDecimal result = BigDecimal.valueOf(longValue).divide(BigDecimal.valueOf(100));
回到您的代码,还有很多其他问题:
您的字符串连接逻辑效率很低。您可以使用StringBuilder或我建议的其他方式
进行比较时,不需要将字符转换为字符串。那么你呢
if (!(".").equals(String.valueOf(c))) {
应该写
if (c != '.') {
您可以简单地使用regex清理输入字符串:
String cvalue = stringNumber.replaceAll("[.,-]", "");
首先,您的转换逻辑很奇怪: 你正在撕掉所有的-,和。在构造BigDecimal时,假设它是2位小数 这意味着,如果给您一个字符串1234.5678,那么您将构建123456.78作为结果 根据您的意图,以下是答案: 如果要根据输入字符串中的值转换为BigDecimal 这意味着,如果希望字符串1234.5678在BigDecimal中变成1234.5678,可以使用DecimalFormat,如本问题所述: 如果奇怪的逻辑是你想要做的 这意味着,如果希望字符串1234.5678在BigDecimal中变为123456.78,那么代码中的具体问题是要进行长除法,并使用结果构造BigDecimal 在Java和许多其他语言中,整数与整数的除法得到的结果是整数,所以123456/100得到的结果是1234 你想要达到的目标可以通过
BigDecimal result = BigDecimal.valueOf(longValue).divide(BigDecimal.valueOf(100));
回到您的代码,还有很多其他问题:
您的字符串连接逻辑效率很低。您可以使用StringBuilder或我建议的其他方式
进行比较时,不需要将字符转换为字符串。那么你呢
if (!(".").equals(String.valueOf(c))) {
应该写
if (c != '.') {
您可以简单地使用regex清理输入字符串:
String cvalue = stringNumber.replaceAll("[.,-]", "");
所以你想把5.326.236,56转换成532623656?也许你应该用Double或Float代替Longim把5.326.236,56转换成532623656,但是当我除以100得到最后两位小数时,bigdecim等于5326236.00I总是用S
实例化BigDecimal的字符串值:BigDecimal bd=new BigDecimal5326236.56。这样你就不会失去任何精度。Long.parseLongcvalue/100会给你一个Long。所以你试图将5.326.236,56转换为532623656?也许你应该使用Double或Float而不是Longim将5.326.236,56转换为532623656,但是当我除以100得到最后两位小数时,Bigdecimal等于5326236.00I始终使用字符串值实例化Bigdecimal:Bigdecimal bd=new BigDecimal5326236.56。这样你就不会失去任何精度。Long.parseLongcvalue/100给了你一个Long。谢谢你,exelent解释,现在在水下工作谢谢你,exelent解释,现在在水下工作。我总是得到精度为两位小数的数字,而不是三位或更多的数字,然后改进代码,非常感谢。我总是能得到精度为两位小数的数字,而不是三位或更多,在改进代码时,非常感谢。