Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我会失去大十进制精度?_Java_Hibernate - Fatal编程技术网

Java 为什么我会失去大十进制精度?

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 (

我正在从txt转换数字,如5.326.236,56 money,并首先删除点和逗号,但我丢失了小数,我已经将列定义为:

@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解释,现在在水下工作。我总是得到精度为两位小数的数字,而不是三位或更多的数字,然后改进代码,非常感谢。我总是能得到精度为两位小数的数字,而不是三位或更多,在改进代码时,非常感谢。