在不丢失格式的情况下将 String 转换为 BigDecimal

Convert String to BigDecimal without losing format

我正在尝试将字符串转换为 BigDecimal,但无法保留格式。字符串是一个 price/number,格式可以是 #,###.00 或 # ###,00

这是我试过的方法,但它不能保持格式完整。 37,717,840.33 ==> 37717840.33

public static BigDecimal convertStringtoDecimal(String patternDecimalFormat, 
String pattern, String price) { 

    DecimalFormatSymbols symbols = new DecimalFormatSymbols();
    symbols.setDecimalSeparator(pattern.charAt(0));
    symbols.setGroupingSeparator(pattern.charAt(1));
    DecimalFormat decimalFormat = new DecimalFormat(patternDecimalFormat, symbols);
    decimalFormat.setParseBigDecimal(true);

    BigDecimal bigDecimal = null;
    try {
        bigDecimal = (BigDecimal) decimalFormat.parse(price);
    } catch (ParseException e) { 

        LOGGER.warn("Exception convertion string to dec", e);
    }
    return bigDecimal ;

}

删除字符串中的逗号。

String price = "1,000,000,000.999999999999999";
BigDecimal result = new BigDecimal(value.replaceAll(",", ""));
System.out.println(result);

A BigDecimal 是一个“[i]可变的、任意精度的带符号十进制数[]”。

什么是“任意精度”?这个Wikipedia article在介绍中是这样说的:

In computer science, arbitrary-precision arithmetic, also called bignum arithmetic, multiple-precision arithmetic, or sometimes infinite-precision arithmetic, indicates that calculations are performed on numbers whose digits of precision are limited only by the available memory of the host system. This contrasts with the faster fixed-precision arithmetic found in most arithmetic logic unit (ALU) hardware, which typically offers between 8 and 64 bits of precision.

换句话说,BigDecimal 是一种特殊类型的 Number,允许“完美”(它不能处理无理数)精度。这与具有“固定精度”的 Double(或基本类型 double)形成对比,因此不能表示 BigDecimal 可以表示的所有数字。这种精度的提高是以增加内存使用和更慢的数学运算为代价的(计算机可以在硬件级别处理 doubles 等)。

我为什么要提出这一切?因为我想指出 BigDecimal 只不过是一个 花哨的数字 。数字,至少在 Java 中,没有格式化的概念。考虑到这一点,您意识到期望 BigDecimal 保持用于创建它的 String 的格式是没有意义的。在您自己的代码中有这方面的提示;您必须使用中间对象 DecimalFormat 将您的 String 解析为 BigDecimal。当 BigDecimal 有一个采用 String 的构造函数时,为什么你必须这样做?这是因为 BigDecimal 构造函数非常有限。如果您尝试使用构造函数转换 String,您会得到带有以下消息的 NumberFormatExcepton:“Character 既不是十进制数字,小数点,也不是"e" 符号指数标记。"

如你所见,正是DecimalFormat理解了你代码中的String。这是因为 这就是 DecimalFormat 设计的。 class 存在,因此您可以使用指定的模式(通常基于用户的Locale)。当您想要显示 Number,例如 BigDecimal,但以格式化的方式显示时,您必须使用 class,例如 DecimalFormat。将数字转换为 String 的一些选项是:

正如我在问题评论中指出的那样,在您的情况下,您应该能够通过调用

取回格式化的 String
String formattedString = decimalFormat.format(bigDecimal);

相同的 DecimalFormat 或至少一个配置相同的。

删除字符串中的逗号。

导入java.math.BigDecimal;


    String price = "1,000,000,000.999999999999999";
    BigDecimal result = new BigDecimal(price.replaceAll(",", ""));
    System.out.println("Prueba: " + result.toString());

//结果:1000000000.999999999999999