为什么我会失去Bigdecimal精度?

时间:2018-10-24 14:49:25

标签: java hibernate

我正在从5.326.236,56转换为txt(货币)之类的数字,并首先删除点和逗号,但是我丢失了小数点,并且我已经将列定义为:

@Column(name = "total", precision = 16, scale = 2)
private BigDecimal total;

但是我丢失了与Decimal部分相对应的后两位数字

这是我的代码:

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;
}

2 个答案:

答案 0 :(得分:4)

基本上,您是在构造long之前对BigDecimal进行整数除法。

自然地,整数除法会产生另一个long ...,它不能表示小数点后的那两位。

您可以通过使用BigDecimal进行除法来避免这种情况:

BigDecimal bigDecimal = BigDecimal.valueOf(Long.parseLong(cvalue))
        .divide(new BigDecimal(100));

或者,如果您不需要实施cvalue是有效的整数(长整数)表示形式的约束,则:

BigDecimal bigDecimal = (new BigDecimal(cvalue))
        .divide(new BigDecimal(100));

可能有更好的方法。 DecimalFormat类可理解各种(本地化)数字格式。如果创建合适的格式,然后调用setParseBigDecimal(true),则格式的parse方法将直接产生BigDecimal ... ...而无需进行任何字符串扑打操作即可摆脱逗号和句点字符。 (而且您无需假设输入数字在小数点后正好是两位数。)

答案 1 :(得分:0)

首先,您的转换逻辑很奇怪:

您要从字符串中剥离所有-,.,并在构造BigDecimal时假定其为2个小数。

这意味着,如果给您一个字符串1234.5678,则将构建123456.78作为结果。

根据您的意图,以下是答案:

  1. 如果要基于输入字符串中的值转换为BigDecimal

    这意味着,如果您希望String "1,234.5678"在BigDecimal中成为1234.5678,则可以使用DecimalFormat,如此问题所述:https://stackoverflow.com/a/18231943/395202

  2. 如果您打算执行奇怪的逻辑

    这意味着,如果您希望String "1,234.5678"在BigDecimal中成为123456.78,则代码中的特定问题是您正在进行长除法,然后使用结果构造BigDecimal。

    在Java(以及其他许多语言)中,将整数除以整数将得到整数,因此123456 / 100将给您1234

    您想要实现的目标可以通过

    完成
    BigDecimal result = BigDecimal.valueOf(longValue).divide(BigDecimal.valueOf(100));
    

    回到您的代码,还有很多其他问题:

    1. 您的字符串连接逻辑效率很低。您可以使用StringBuilder(或我建议的其他方式)
    2. 您不需要将char转换为String即可进行比较。所以你

      if (!(".").equals(String.valueOf(c))) {
      

      应写成

      if (c != '.') {
      
    3. 您可以简单地使用正则表达式来清理您的输入字符串:

      String cvalue = stringNumber.replaceAll("[.,-]", "");