格式化数字 - Java 中的小数位数字分组

Formatting numbers - grouping of decimal-place digits in Java

DecimalFormat class 是否支持小数位数字分组,类似于通过方法 setGroupingUsed()setGroupingSize 对数字整数部分所做的分组?

我希望将号码 123456.789012 格式化为 123,456.789,012

根据 API guide:

The grouping separator is commonly used for thousands, but in some countries it separates ten-thousands. The grouping size is a constant number of digits between the grouping characters, such as 3 for 100,000,000 or 4 for 1,0000,0000. If you supply a pattern with multiple grouping characters, the interval between the last one and the end of the integer is the one that is used. So "#,##,###,####" == "######,####" == "##,####,####".

这段话表明分组符号只能应用于数字的整数部分。如果我们设置这样的模式:

String pattern = "###,###.###,###";

传给DecimalFormat的一个实例,结果是:

java.lang.IllegalArgumentException: Malformed pattern "###,###.###,###"

而更典型的是:

String pattern = "###,###.###";

按预期工作。

setGroupingUsed 不适用,因为它需要一个布尔值来指示该数字是否将用分组数字表示。 setGroupingSize 也不适用,因为它只规定每组有多少位数字。

获得所需内容的唯一方法是推出自己的格式化程序。

附录:

破解DecimalFormatsource发现要格式化的数字分为三段:leftDigits,即数字整数部分最左边的数字, zeroDigits,即整数部分最右边的数字,rightDigits,即数字的小数部分。

代码包括以下内容(注释从第2507行开始):

// The position of the last grouping character is
// recorded (should be somewhere within the first two blocks
// of characters)

注释中的“块”明确指的是 leftDigitszeroDigits,因此即使是开发人员也假设分组数字只会出现在整数部分,并且没有对分组进行任何规定小数部分(抛出异常除外)。

小数点后没有分组。这样的格式将无效并抛出异常。