基于Java,介绍将浮点类型小数进行格式化的方案。
正文
在Java中,用于格式化小数的类是java.text.DecimalFormat,比如你可以这样使用:
double data = 3334590479.22d;
System.out.println(data); // 3.33459047922E9
java.text.DecimalFormat df = new java.text.DecimalFormat("$#,###.##");
String result = df.format(data);
System.out.println(result); // $3,334,590,479.22
对于比较大的数值,模式使用科学表示法(scientific notation);使用java.text.DecimalFormat指定格式,则用指定的格式。
格式"$#,###.##"包含以下语义:
1. 前缀为$
2. 整数部分每3位数为一组
3. 最多保留2位小数
关于格式
一个格式的大致结构是:Prefixopt Number Suffixopt,即前缀 + 数字 + 后缀;其中前缀和后缀都是可选的。
关于分组
组分隔符使用,且只能在整数部分使用;不管模式中有多少个分隔符,最右边的那一个有效;每一组的个数就是最右边的分隔符之右的整数位数。
所以"#,##,###,####" == "######,####" == "##,####,####"。
关于小数
小数分隔符使用.,用以分隔整数部分和小数部分。
关于数字特殊字符
1. #
#是一个特殊字符,用于数字部分;它表示显示数字,但是最前面和最后面的0不予显示。
data:02222.20
pattern:",###.##"
result:2,222.2
#用于整数部分没有数位的限制,但是用于小数部分,却有“最多只能有多少位小数的意思”,多余的进行舍入。比如:
data:2222.222
pattern:",###.##"
result:2,222.22
2. 0
0和#的用法是相近的,却又略有不同;不同之处在于:
a. 0限制整数部分最少出现的位数;不足这个位数的,前面补0
data:22.26
pattern:"0,000.00"
result:0,022.26
b. 0限制小数部分出现的位数;不足补0,多的舍入
data:22.26
-----------------
pattern:"00.000"
result:22.260
-----------------
pattern:"00.0"
result:22.3
3. E
科学表示法,尾数和指数的分隔符。
具体内容见后文。
关于前缀、后缀
除\uFFFE, \uFFFF和特殊字符之外的任意Unicode字符,都可以作为前缀、后缀;有四个特殊的字符:
1. %
将数字乘以100
data:1234.567
pattern:",###.##%"
result:123,456.7%
2. \u2030
将数字乘以1000
data:1234.567
pattern:",###.##\u2030"
result:1,234,567‰
3. ¤(\u00A4)
本地化货币符号,如果连续出现两次,代表货币符号的国际代号。
data:1234.567
---------------------
pattern:",###.##¤"
result:1,234.57¥
---------------------
pattern:",###.##¤¤"
result:1,234.57CNY
4. '
用于引用特殊的字符,作为前缀或后缀。
data:1234.567
pattern:"'#',###.##"
result:#1,234.57
如果想使用'本身作为前缀或后缀,连续输入两次:
data:1234.567
pattern:"'',###.##"
result:'1,234.57
关于科学表示法
科学表示法是在数字部分的尾部添加如E0的内容,其中E是尾数和指数的分隔符,E后面的0的个数表示指数的最少位数(不足前面补0)。
data:1E5
pattern:0.#E00
result:1E05 // 注意指数有2位
E的前面必须要有内容,至少要有一个#或者0,否则E就被当作前缀处理了:
data:1E5
---------------
pattern:"E0"
result:E100000
---------------
pattern:"0E0"
result:1E5
---------------
pattern:"#E0"
result:.1E6
指数部分没有多少内容,下面讨论尾数部分。
尾数一般包括整数和小数,如果整数部分没有内容(.前面没有内容),有效数字就全部在小数上:
data:12345E5
pattern:".###E0"
result:.123E10
如果整数部分需要保留几位数,就使用几个0(使用#的结果有点匪夷所思,大家自行尝试):
data:12345E5
----------------------
pattern:"0.###E0"
result:1.234E9
----------------------
pattern:"00.###E0"
result:12.345E8
---------------------
pattern:"000.###E0"
result:123.45E7
小数部分,如果想实现“最多保留几位小数”的效果,在pattern的.之后添加相应个#。这样,多余的会舍入;如果想实现“恰好保留几位小数”的效果,在pattern的.之后添加相应个0。这样,缺少会在后面补0,多余的会舍入。
data:123E5
------------------
pattern:"0.#E0"
result:1.2E7
------------------
pattern:"0.##E0"
result:1.23E7
------------------
pattern:"0.###E0"
result:1.23E7
==================
pattern:"0.0E0"
result:1.2E7
------------------
pattern:"0.00E0"
result:1.23E7
------------------
pattern:"0.000E0"
result:1.230E7