格式化数字 - Java 中的小数位数字分组
Posted
技术标签:
【中文标题】格式化数字 - Java 中的小数位数字分组【英文标题】:Formatting numbers - grouping of decimal-place digits in Java 【发布时间】:2021-05-17 01:09:06 【问题描述】:DecimalFormat
类是否支持小数位数分组,类似于通过方法 setGroupingUsed()
和 setGroupingSize
对数字的整数部分进行分组?
我希望将数字 123456.789012 格式化为 123,456.789,012
。
【问题讨论】:
你试过了吗? 我还没有听说这样做过。这是任何特定国家/地区的标准数字格式吗?如果是这样,您是否尝试过使用该国家/地区的语言环境? 我从未见过这样的格式。 更常见的格式是 123,456.789012 有趣的是,Wikipedia 文章有这样的说法:“在某些国家,这些‘数字组分隔符’仅用于小数分隔符的左侧;在其他国家,它们也用于用长小数部分分隔数字。”然而,这篇文章没有提到哪些国家使用每种风格。 【参考方案1】:根据API guide:
分组分隔符通常用于千位,但在某些情况下 它分隔一万个国家。分组大小是一个常数 分组字符之间的位数,例如 3 表示 100,000,000 或 4 对应 1,0000,0000。如果你提供一个模式 多个分组字符,最后一个和之间的间隔 整数的结尾是使用的那个。所以“#,##,###,####”== "######,####" == "##,####,####"。
这段话表明分组符号只能应用于数字的整数部分。如果我们设置这样的模式:
String pattern = "###,###.###,###";
并将其传递给DecimalFormat
的实例,结果为:
java.lang.IllegalArgumentException: Malformed pattern "###,###.###,###"
而更典型的:
String pattern = "###,###.###";
按预期工作。
setGroupingUsed
不适用,因为它需要一个布尔值来指示数字是否将用分组数字表示。 setGroupingSize
也不适用,因为它只控制每个组的位数。
获得所需内容的唯一方法是推出自己的格式化程序。
附录:
破解DecimalFormat
的source会发现要格式化的数字分为三部分:leftDigits
,或数字整数部分最左边的数字zeroDigits
,或最右边的数字数字的整数部分,rightDigits
,或数字的小数部分。
代码包括以下内容(注释从第 2507 行开始):
// The position of the last grouping character is
// recorded (should be somewhere within the first two blocks
// of characters)
注释中的“块”显然是指leftDigits
和zeroDigits
,因此即使是开发人员也认为分组数字只会出现在整数部分,并且没有规定在小数部分进行分组(除了抛出例外)。
【讨论】:
这真是令人失望。对我来说,小数点右侧每 3 位有逗号看起来很正常。我本来希望 DecimalFormat 开箱即用。 @DawoodibnKareem 出于好奇,您是否熟悉哪些国家或行业在数字的小数部分使用分组数字?除了每五位数用稀疏空间分组的数学家之外,我在网上找不到任何东西。 ISO 标准似乎是用点或逗号来表示用于分组的小数和细空格,但它没有提到在小数部分进行分组。 精美呈现! 不,我真的不是。实际上,我对这个问题下的三个 cmets 感到非常惊讶 - 其中两个评论员否认看到/听到了这个,一个说它比省略逗号更常见。【参考方案2】:小数点后没有分组。这样的格式会无效并抛出异常。
【讨论】:
什么代码会抛出异常,什么异常? 小数点后的逗号以上是关于格式化数字 - Java 中的小数位数字分组的主要内容,如果未能解决你的问题,请参考以下文章