Java中實現數字金額到中文大寫字元的轉換!!
最近用到了數值轉成大寫人民幣的功能,在網上找了一下只有C++版的,好容易找到一個java版的竟然收費!!沒辦法就自己弄一個出來,想必用到該功能的人肯定少,就拿出來與大家共享!!
/**
* <p>Title: money</p>
* <p>Description:
* *該類是把阿拉伯數字轉換成中文大寫的類。根據王大慶兄的C++程式稍做修改而成,後面附有王大慶兄的C++
* *程式,如果對所附的C++程式有什麼問題請與王大慶兄聯絡email: [email protected]
* *如果對java部分有什麼看法和建議請與小弟聯絡,楊璇 email:
* *類名:money
* *函式:String PositiveIntegerToHanStr(String NumStr) 負責把小數點前面的數轉換為大寫中文
* *函式:String NumToRMBStr(double val) 負責把輸入的double型的數轉換為大寫中文
* *注意java程式轉換的範圍是:小數點前面15位(已測試通過),C++程式是24位(我沒有測試)
* </p>
* <p>Copyright: Copyright (c) 2003 你可以對本程式隨意修改,複製,使用,但請保留這裡註釋宣告!!!</p>
* <p>Company: </p>
* @author 王大慶、楊璇
* @version 1.0
*/
import java.lang.Math;
public class money{
//除錯時用main函式
public static void main(String args[]){
money mon = new money();
System.out.println(-99999999999999.999+mon.NumToRMBStr(-99999999999999.999));
System.out.println(99999999999999.999+mon.NumToRMBStr(99999999999999.999));
System.out.println(mon.NumToRMBStr(100000000.00));
System.out.println(mon.NumToRMBStr(100000001.00));
}
String HanDigiStr[] = new String[]{"零","壹","貳","叄","肆","伍","陸","柒","捌","玖"};
String HanDiviStr[] = new String[]{"","拾","佰","仟","萬","拾","佰","仟","億",
"拾","佰","仟","萬","拾","佰","仟","億",
"拾","佰","仟","萬","拾","佰","仟" };
String PositiveIntegerToHanStr(String NumStr)
{ // 輸入字串必須正整數,只允許前導空格(必須右對齊),不宜有前導零
String RMBStr = "";
boolean lastzero = false;
boolean hasvalue= false; // 億、萬進位前有數值標記
int len,n;
len = NumStr.length();
if( len > 15 ) return "數值過大!";
for(int i=len-1;i>=0;i--) {
if( NumStr.charAt(len-i-1)==' ' ) continue;
n = NumStr.charAt(len-i-1) - '0';
if( n<0 || n>9 ) return "輸入含非數字字元!";
if( n!=0 ) {
if( lastzero ) RMBStr += HanDigiStr[0]; // 若干零後若跟非零值,只顯示一個零
// 除了億萬前的零不帶到後面
//if( !( n==1 && (i%4)==1 && (lastzero || i==len-1) ) ) // 如十進位前有零也不發壹音用此行
if( !( n==1 && (i%4)==1 && i==len-1 ) ) // 十進位處於第一位不發壹音
RMBStr += HanDigiStr[n];
RMBStr += HanDiviStr[i]; // 非零值後加進位,個位為空
hasvalue = true; // 置萬進位前有值標記
}else {
if( (i%8)==0 || ((i%8)==4 && hasvalue) ) // 億萬之間必須有非零值方顯示萬
RMBStr += HanDiviStr[i]; // “億”或“萬”
}
if( i%8==0 ) hasvalue = false ; // 萬進位前有值標記逢億復位
lastzero = (n==0) && (i%4!=0);
}
if( RMBStr.length()==0 ) return HanDigiStr[0]; // 輸入空字元或"0",返回"零"
return RMBStr;
}
String NumToRMBStr(double val)
{
String SignStr ="" ;
String TailStr ="";
long fraction, integer;
int jiao,fen;
if( val<0 ) {
val = -val;
SignStr = "負";
}
if(val > 99999999999999.999 || val <-99999999999999.999 ) return "數值位數過大!";
// 四捨五入到分
long temp = Math.round(val*100);
integer = temp/100;
fraction = temp%100;
jiao = (int)fraction/10;
fen = (int)fraction%10;
if( jiao==0 && fen==0 ) {
TailStr = "整";
}
else {
TailStr = HanDigiStr[jiao];
if( jiao!=0 )
TailStr += "角";
if( integer==0 && jiao==0 ) // 零元后不寫零幾分
TailStr = "";
if( fen!=0 )
TailStr += HanDigiStr[fen] + "分";
}
// 下一行可用於非正規金融場合,0.03只顯示“叄分”而不是“零元叄分”
// if( !integer ) return SignStr+TailStr;
return "¥"+SignStr+PositiveIntegerToHanStr(String.valueOf(integer) )+"元"+TailStr;
}
}//END public class money
//附王大慶兄的C++的源程式:
//rmb.cpp
/*
#include <vcl.h> // must define AnsiString before rmb.h
#pragma hdrstop // only for C++ Builder
#include <math.h>
#include "rmb.h"
//---------------------------------------------------------------------------
// 常量字串定義,如修改也可變為轉換普通漢字函式(如:一二三,十百千)
const char *HanDigiStr[] = {"零","壹","貳","叄","肆","伍","陸","柒","捌","玖"};
const char *HanDiviStr[] = { "","拾","佰","仟","萬","拾","佰","仟","億",
"拾","佰","仟","萬","拾","佰","仟","億",
"拾","佰","仟","萬","拾","佰","仟" };
AnsiString PositiveIntegerToHanStr(const AnsiString &NumStr)
{ // 輸入字串必須正整數,只允許前導空格(必須右對齊),不宜有前導零
AnsiString RMBStr;
int len,n,lastzero=0;
int hasvalue=0; // 億、萬進位前有數值標記
len = NumStr.Length();
if( len > 24 ) return "數值過大!";
for(int i=len-1;i>=0;i--) {
if( NumStr[len-i]==' ' ) continue; // AnsiString[] base is 1
n = NumStr[len-i] - '0';
if( n<0 || n>9 ) return "輸入含非數字字元!";
if( n!=0 ) {
if( lastzero ) RMBStr += HanDigiStr[0]; // 若干零後若跟非零值,只顯示一個零
// 除了億萬前的零不帶到後面
// if( !( n==1 && (i%4)==1 && (lastzero || i==len-1) ) ) // 如十進位前有零也不發壹音用此行
// if( !( n==1 && (i%4)==1 && i==len-1 ) ) // 十進位處於第一位不發壹音
RMBStr += HanDigiStr[n];
RMBStr += HanDiviStr[i]; // 非零值後加進位,個位為空
hasvalue = 1; // 置萬進位前有值標記
}
else {
if( (i%8)==0 || ((i%8)==4 && hasvalue) ) // 億萬之間必須有非零值方顯示萬
RMBStr += HanDiviStr[i]; // “億”或“萬”
}
if( i%8==0 ) hasvalue = 0; // 萬進位前有值標記逢億復位
lastzero = (n==0) && (i%4!=0); // 億萬前有零後不加零,如:拾萬貳仟
}
if( RMBStr.Length()==0 ) return HanDigiStr[0]; // 輸入空字元或"0",返回"零"
return RMBStr;
}
AnsiString NumToRMBStr(double val)
{
AnsiString SignStr,TailStr;
double fraction, integer;
int jiao,fen;
if( val<0 ) {
val = -val;
SignStr = "負";
}
fraction = modf(val+0.005, &integer); // 四捨五入到分
jiao = int(fraction*10);
fen = int(fraction*100)-jiao*10;
if( jiao==0 && fen==0 ) {
TailStr = "整";
}
else {
TailStr = HanDigiStr[jiao];
if( jiao!=0 )
TailStr += "角";
if( integer==0 && jiao==0 ) // 零元后不寫零幾分
TailStr = "";
if( fen!=0 )
TailStr += HanDigiStr[fen] + AnsiString("分");
}
// 下一行可用於非正規金融場合,0.03只顯示“叄分”而不是“零元叄分”
// if( integer==0 ) return SignStr+TailStr;
return SignStr+PositiveIntegerToHanStr( AnsiString(integer) )+"元"+TailStr;
}
//下面是rmb.h
#ifndef rmbH
#define rmbH
// for AnsiString def
// #include <vcl.h>
// 數值轉大寫人民幣函式
AnsiString NumToRMBStr(double val);
// 正整數字符串轉漢字函式,不建議單獨使用
// 輸入字串必須正整數,只允許前導空格(必須右對齊),不宜有前導零
// AnsiString PositiveIntegerToHanStr(const AnsiString &NumStr);
#endif
//-----------------------------------------------------------
// 基本考慮
// 人民幣大寫單位銀行規定用“元”
// 無零頭金額後跟“整”,有則不跟
// 角為零時不寫角(如:零叄分)
// 四捨五入到分
// 為減少判讀疑惑(一般對大寫金額預期較高)和
// 體現人民幣基本單位為元,金額低於壹圓前仍加“零元”
// 整數轉換
// 若干零後若跟非零值,只顯示一個零,否則不顯示
// 萬(億)前有零後不加零,因億、萬為一完整單位,
// (如:拾萬貳仟 比 拾萬零貳仟 更順些)
// 億為漢語計數最大單位,只要進位到總是顯示(如:壹億億)
// 萬為次最大單位,億萬之間必須有非零值方顯示萬
// (如“壹億”不可顯示為“壹億萬”)
//
// 為減少被竄改的可能性,十進位總髮壹音,這和下面的習慣讀法不一樣
// (十進位處於第一位不發壹音,如“拾元”非“壹拾元”,
// 十進位處前有零是否不發壹音不太確定,
// 如“叄仟零壹拾元”還是“叄仟零拾元”?)
// 用“拾萬”不用“壹拾萬”,因為每個整數進位後都有進位單位(拾佰仟萬億)
// 這樣即使金額前沒有附防竄改的字首如“人民幣”字樣也難竄改些
// 因為至少要加添兩個漢字並且改動後數字必須進位才能竄改成
// (如“拾萬”可改成“叄拾萬”,而“壹拾萬”至少要改成“壹佰壹拾萬”)
// 此函式為Borland C++ Builder編寫,已充分考慮到跨平臺相容性
// 如需轉換到其它場合,
// 只需修改字串型別從AnsiString到對應的型別、功能及函式
// (注意兩個char*型字串不可以直接相加,需有一個先轉換)
// public domain freeware by 王大慶 2003年3月-5月 v1.1
// 此函式如有不妥之處請email: [email protected]
*/