带大括号的 Java 负 bigdecimal 值

Posted

技术标签:

【中文标题】带大括号的 Java 负 bigdecimal 值【英文标题】:Java negative bigdecimal value with braces 【发布时间】:2013-02-13 17:41:06 【问题描述】:

我有一个字符串,我正试图将其解析为 BigDecimal。我正在使用以下正则表达式来去除除 -,.()$ 之外的所有非货币符号。一旦它被剥离,我就会尝试用剩余的值创建一个 BigDecimal。当括号中出现负值时,问题就开始了。有人对如何修复此实例有任何建议吗?

(1000.00) fails

我假设我必须以某种方式将括号转换为负号。

代码示例。

public BigDecimal parseClient(Field field, String clientValue, String message) throws ValidationException 
    if (clientValue == null) 
        return null;
    

    try 
        clientValue = clientValue.replaceAll( "[^\\d\\-\\.\\(\\)]", "" );
        return new BigDecimal(clientValue.toString());
     catch (NumberFormatException ex) 
        throw new ValidationException(message);
    

【问题讨论】:

您没有描述输入字符串的格式。真的很奇怪,不能使用 DecimalFormat 实例来解析字符串吗?如果不是,你为什么要通过自己操纵字符串来重新发明***? 这有帮助吗:***.com/questions/2056400/… 这些值由用户输入。这些值非常类似,$5,000.00, 5,000.00, 5000.00, 5000, -5000.00, (5000.00), ($5000.00), (-5000.00), ($-5000.00)。最后,它们需要是 5000.00、(-5000.00)、-5000.00,以便它们可以被传递成一个大数。 @GJ13,我看过那个帖子,但我不明白该格式会如何去除不需要的字符。 【参考方案1】:

您需要自己检测() 字符,然后将它们去掉,从字符串的其余部分创建一个BigDecimal,然后取反。

if (clientValue.startsWith('(') && clientValue.endsWith(')'))

   return new BigDecimal(clientValue.substring(1, clientValue.length() - 1)).negate();

else

   return new BigDecimal(clientValue);

【讨论】:

这几乎可以工作,但是当你有 (-1000.00) 这是一个有效值时否定为正 1000.00 那么你需要在子字符串的开头检测一个可能的'-'字符,如果它在那里,不要否定,这样你的结果就会保持否定。 这就是我所做的,尽管在数学上这不会是一个负数? 负数有两种表示方式:正常的数学减号,例如-1000.00,和会计方式,例如。 (1000.00)。您的第一条评论表明,如果两者都给出,例如(-1000.00),该数字应保持为负数。这就是我在上面发表第一条评论的原因。【参考方案2】:

是什么让您认为BigDecimal 正确解释了括号? (1000.00) 输入错误 according to the documentation。您必须使用 - 符号 (-1000.00)。 JavaDoc 中严格定义了支持的格式。一般来说,它是可选符号(+-),后跟数字、点(.)和指数。

例如这是有效的输入:-1.1e-10

【讨论】:

那么您建议在第一个大括号后附加负号? 好的,我必须简单地忽略这一点,因为 CurrencyFormatter 将值发送到前端而没有减号导致它在提交到后端时失败。【参考方案3】:

DecimalFormat 是更适合这项工作的工具:

DecimalFormat myFormatter = new DecimalFormat("¤#,##0.00;(¤#,##0.00)");
myFormatter.setParseBigDecimal(true);
BigDecimal result = (BigDecimal) myFormatter.parse("(1000.00)");
System.out.println(result); // -1000.00 for Locale.US
System.out.println(myFormatter.parse("($123,456,789.12)")); // -123456789.12

如您所见,它不仅会处理负面模式,还会处理货币符号、小数和分组分隔符、本地化问题等。

查看The Java Tutorials: Customizing Formats 了解更多信息。

【讨论】:

以上是关于带大括号的 Java 负 bigdecimal 值的主要内容,如果未能解决你的问题,请参考以下文章

React:带大括号的参数与不带大括号的参数之间的区别

带/不带大括号的 C# Switch 语句....有啥区别?

c#不带大括号的记录

如何删除字典外部大括号或将其不带大括号附加到列表中?

带大括号的 SQL 运算符优先级

在 ES6 中导入带或不带大括号 [重复]