Posted on 2006-11-06 22:29
大大毛 阅读(3398)
评论(0) 编辑 收藏 所属分类:
JAVA
昨天,在群上谈论到货币金额大写转换的问题,有空就自己做了一个。
在实现过程中由于采用的解决方法而遇到一点问题:
由于输入的是一个货币数字字符串,因此对输入的合法性检验必不可少,讨论中提到有用正则来进行检验,不过这个我不在行,所以我的思路是利用JDK自带的类型转换来完成,但是在先前使用 Double.parseDouble(String money); 时碰到了字符长度的限制,长了一点就会超出double的取值范围,后来转而使用 java.math.BigDecimal 类来实现字符串的检验以及一点点变换。
考虑到以后使用中的通用性,因此把各位的符号(如仟,佰,拾,万等)提了出来,这样如果以其它的形式(如E文)表现,不会影响到实现。
小数后精度的考虑,我想一个字符型货币不一定就只能到小数后两位的,因此没有依赖于2位小数的实现,而是根据小数后单位符号的个数来规定精度。例如将小数后的符号由 {"角","分"} 改成 {"角","分","厘"} 的话,就可以实现对小数后三位的格式化输出。
在实现中,我开放了两个接口,以便使用
/**
* 货币数字形式转换成大写
*
@param
strMoney(String):货币的数字形式字符串
*/
public
static
String parseMoney(String strMoney)
throws
NumberFormatException
这个接口,是用于检验+转换的,它可以实现该类的全部功能
/**
* 转换成大写金额
*
@param
strMoney(String):规范的数字货币形式字符串
*/
public
static
String toFrmString(String strMoney)
这个接口,我也开放出来,在实现中它完成部分功能,仅仅提供对无符号货币形式的转换,它完成转换的核心逻辑,开放它是出于以后能使用新增的输入检验逻辑。
整个类的实现(没有想到好名称,所以就随便取了一个):
类实现代码
import
java.io.
*
;
import
java.math.BigDecimal;
public
class
T3 {
public
static
final
boolean
NEGATIVE
=
false
;
//
是否允许负数表示
public
static
final
String[][] CAPITAL;
static
{
CAPITAL
=
new
String[][]{
{
"
零
"
,
"
壹
"
,
"
贰
"
,
"
叁
"
,
"
肆
"
,
"
伍
"
,
"
陆
"
,
"
柒
"
,
"
捌
"
,
"
玖
"
},
//
0-9
{
"
拾
"
,
"
佰
"
,
"
仟
"
},
//
拾,佰,仟
{
"
万
"
},
//
万
{
"
亿
"
},
//
亿
{
"
元
"
},
//
个位
{
"
角
"
,
"
分
"
},
//
小数位,{"角","分","厘"}
{
"
正
"
,
"
负
"
}
//
正负数的前缀形式,当NEGATIVE=true时生效
};
}
/**
* 转换成大写金额
*
@param
strMoney(String):规范的数字货币形式字符串
*/
public
static
String toFrmString(String strMoney) {
StringBuffer sb
=
new
StringBuffer(
100
);
String[] tmp
=
strMoney.trim().split(
"
\\.
"
);
//
--------整数位处理---------------
char
[] ci
=
tmp[
0
].toCharArray();
char
theBit
=
'
0
'
;
//
当前数字位
int
zeroBit
=
0
;
//
开始零位
int
bitLen
=
0
;
//
当前位所处的位置(从个位开始0计数)
boolean
flag
=
false
;
//
是否具有有效的整数位
for
(
int
index
=
0
;index
<
ci.length;index
++
) {
theBit
=
ci[index];
//
取出当前处理的整数位
bitLen
=
ci.length
-
index
-
1
;
//
计算当前处理的数处于什么位置
if
(zeroBit
>
0
&&
theBit
!=
'
0
'
){
sb.append(CAPITAL[
0
][
0
]);
//
加前导零
}
if
(theBit
!=
'
0
'
) sb.append(CAPITAL[
0
][theBit
-
'
0
'
]);
//
大写数字
if
(bitLen
%
8
==
0
){
if
(bitLen
==
0
){
//
元
if
(ci.length
>
1
||
theBit
!=
'
0
'
) sb.append(CAPITAL[
4
][
0
]);
//
元
}
else
{
//
亿
sb.append(CAPITAL[
3
][
0
]);
//
亿
}
}
else
{
if
(bitLen
%
4
==
0
){
//
万
if
(theBit
!=
'
0
'
||
zeroBit
==
0
||
zeroBit
-
bitLen
<
3
){
sb.append(CAPITAL[
2
][
0
]);
//
万
}
}
else
{
//
仟佰拾
if
(theBit
!=
'
0
'
) sb.append(CAPITAL[
1
][bitLen
%
4
-
1
]);
//
仟佰拾
}
}
//
检查并条件更新零位
if
(theBit
==
'
0
'
){
zeroBit
=
zeroBit
==
0
?
bitLen:zeroBit;
}
else
{
zeroBit
=
0
;
flag
=
true
;
}
}
//
--------小数位处理---------------
char
[] cf
=
null
;
if
(tmp.length
>
1
){
cf
=
tmp[
1
].toCharArray();
for
(
int
index
=
0
;index
<
cf.length;index
++
) {
theBit
=
cf[index];
//
取出当前处理的小数位
if
(zeroBit
>
0
&&
theBit
!=
'
0
'
&&
flag){
sb.append(CAPITAL[
0
][
0
]);
//
加前导零
}
if
(theBit
!=
'
0
'
) sb.append(CAPITAL[
0
][theBit
-
'
0
'
]);
//
大写数字
if
(theBit
!=
'
0
'
) sb.append(CAPITAL[
5
][index]);
//
角分
zeroBit
=
theBit
==
'
0
'
?
1
:
0
;
}
}
return
sb.length()
==
0
?
(CAPITAL[
0
][
0
]
+
CAPITAL[
4
][
0
]):sb.toString();
}
/**
* 货币数字形式转换成大写
*
@param
strMoney(String):货币的数字形式字符串
*/
public
static
String parseMoney(String strMoney)
throws
NumberFormatException {
BigDecimal bd
=
new
BigDecimal(strMoney);
//
输入检查
if
(bd.signum()
==
-
1
&&
!
NEGATIVE)
throw
new
NumberFormatException(
"
货币金额不能为负数
"
);
try
{
bd.setScale(CAPITAL[
5
].length);
}
catch
(ArithmeticException e){
throw
new
NumberFormatException(
"
只能为
"
+
CAPITAL[
5
].length
+
"
位小数
"
);
}
//
大写金额转换
if
(NEGATIVE
&&
bd.signum()
!=
0
) {
return
CAPITAL[
6
][bd.signum()
==-
1
?
1
:
0
]
+
toFrmString(bd.abs().toString());
}
else
{
return
toFrmString(bd.toString());
}
}
public
static
void
main(String[] args)
throws
IOException {
String money
=
null
;
System.out.println(
"
请输入合法的货币金额( ^C退出 ):
"
);
BufferedReader br
=
new
BufferedReader(
new
InputStreamReader(System.in));
while
( (money
=
br.readLine())
!=
null
){
if
(money.trim().length()
<
1
)
continue
;
try
{
System.out.println(
"
大写:
"
+
parseMoney(money) );
}
catch
(Exception e){
System.out.println(
"
输入格式不合法,错误信息:
"
+
e.getMessage());
}
}
System.out.println(
"
bye
"
);
}
}
运行:
输入:1023470847959328310393.03
输出:壹拾万零贰仟叁佰肆拾柒亿零捌佰肆拾柒万玖仟伍佰玖拾叁亿贰仟捌佰叁拾壹万零叁佰玖拾叁元零叁分
输入:10010000000
输出:壹佰亿零壹仟万元
输入:.01
输出:壹分