在金额转换时,要求数字和单位转为繁体的.浮点数的话读到小数点后两位,也就是分.
将数字转为繁体的没什么问题,主要是加上单位要考虑的特殊情况,比如1000不能读成1千零零零圆;1010要读成1千零一拾圆;小数点前面是0的就只读角和分...
主要用到数组,还有substring
哪位有没有好的算法可以实现.可以用C#,也可以用ASP.NET
将数字转为繁体的没什么问题,主要是加上单位要考虑的特殊情况,比如1000不能读成1千零零零圆;1010要读成1千零一拾圆;小数点前面是0的就只读角和分...
主要用到数组,还有substring
哪位有没有好的算法可以实现.可以用C#,也可以用ASP.NET
public string ToUpperMoney(decimal d)
{
if (d == 0)
return "零元整";
string je = d.ToString("####.00");
if (je.Length > 15)
return "";
je = new String('0',15 - je.Length) + je; //若小于15位长,前面补0 string stry = je.Substring(0,4); //取得'亿'单元
string strw = je.Substring(4,4); //取得'万'单元
string strg = je.Substring(8,4); //取得'元'单元
string strf = je.Substring(13,2); //取得小数部分
string str1 = "",str2 = "",str3 = ""; str1 = this.getupper(stry,"亿"); //亿单元的大写
str2 = this.getupper(strw,"万"); //万单元的大写
str3 = this.getupper(strg,"元"); //元单元的大写
string str_y = "", str_w = "";
if (je[3] == '0' || je[4] == '0') //亿和万之间是否有0
str_y = "零";
if (je[7] == '0' || je[8] == '0') //万和元之间是否有0
str_w = "零"; string ret = str1 + str_y + str2 + str_w + str3; //亿,万,元的三个大写合并 for (int i = 0 ;i < ret.Length;i++) //去掉前面的"零"
{
if (ret[i] != '零')
{
ret = ret.Substring(i);
break;
} }
for (int i = ret.Length - 1;i > -1 ;i--) //去掉最后的"零"
{
if (ret[i] != '零')
{
ret = ret.Substring(0,i+1);
break;
}
}
if (ret[ret.Length - 1] != '元') //若最后不位不是'元',则加一个'元'字
ret = ret + "元"; if (ret == "零零元") //若为零元,则去掉"元数",结果只要小数部分
ret = "";
if (strf == "00") //下面是小数部分的转换
{
ret = ret + "整";
}
else
{
string tmp = "";
tmp = this.getint(strf[0]);
if (tmp == "零")
ret = ret + tmp;
else
ret = ret + tmp + "角"; tmp = this.getint(strf[1]);
if (tmp == "零")
ret = ret + "整";
else
ret = ret + tmp + "分";
} if (ret[0] == '零')
{
ret = ret.Substring(1); //防止0.03转为"零叁分",而直接转为"叁分"
} return ret; //完成,返回
} public string ToUpperDigit(decimal d)
{
if (d == 0)
return "";
string je = d.ToString("####.00");
if (je.Length > 15)
return "";
je = new String('0',15 - je.Length) + je; //若小于15位长,前面补0 string stry = je.Substring(0,4); //取得'亿'单元
string strw = je.Substring(4,4); //取得'万'单元
string strg = je.Substring(8,4); //取得'元'单元
string strf = je.Substring(13,2); //取得小数部分
string str1 = "",str2 = "",str3 = ""; str1 = this.getupper(stry,"亿"); //亿单元的大写
str2 = this.getupper(strw,"万"); //万单元的大写
if(System.Convert.ToInt32(strf)!=0)
{
str3 = this.getupper(strg,"点"); //元单元的大写
}
else
{
str3=this.getupper(strg,"");
}
string str_y = "", str_w = "";
if (je[3] == '0' || je[4] == '0') //亿和万之间是否有0
str_y = "零";
if (je[7] == '0' || je[8] == '0') //万和元之间是否有0
str_w = "零"; string ret = str1 + str_y + str2 + str_w + str3; //亿,万,元的三个大写合并 for (int i = 0 ;i < ret.Length;i++) //去掉前面的"零"
{
if (ret[i] != '零')
{
ret = ret.Substring(i);
break;
} }
for (int i = ret.Length - 1;i > -1 ;i--) //去掉最后的"零"
{
if (ret[i] != '零')
{
ret = ret.Substring(0,i+1);
break;
}
}
// if (ret[ret.Length - 1] != '') //若最后不位不是'元',则加一个'元'字
// ret = ret + ""; if (ret == "零零") //若为零元,则去掉"元数",结果只要小数部分
ret = "零点";
if (strf == "00") //下面是小数部分的转换
{
ret = ret + "";
}
else
{
string tmp = "";
tmp = this.getint(strf[0]);
if (tmp == "零")
ret = ret + tmp;
else
ret = ret + tmp + ""; tmp = this.getint(strf[1]);
if (tmp == "零")
ret = ret + "";
else
ret = ret + tmp + "";
} //if (ret[0] == '零')
// {
// ret = ret.Substring(1); //防止0.03转为"零叁分",而直接转为"叁分"
// } return ret; //完成,返回
}
/// <summary>
/// 把一个单元转为大写,如亿单元,万单元,个单元
/// </summary>
/// <param name="str">这个单元的小写数字(4位长,若不足,则前面补零)</param>
/// <param name="strDW">亿,万,元</param>
/// <returns>转换结果</returns>
private string getupper(string str,string strDW)
{
if (str == "0000")
return ""; string ret = "";
string tmp1 = this.getint(str[0]) ;
string tmp2 = this.getint(str[1]) ;
string tmp3 = this.getint(str[2]) ;
string tmp4 = this.getint(str[3]) ;
if (tmp1 != "零")
{
ret = ret + tmp1 + "仟";
}
else
{
ret = ret + tmp1;
} if (tmp2 != "零")
{
ret = ret + tmp2 + "佰";
}
else
{
if (tmp1 != "零") //保证若有两个零'00',结果只有一个零,下同
ret = ret + tmp2;
} if (tmp3 != "零")
{
ret = ret + tmp3 + "拾";
}
else
{
if (tmp2 != "零")
ret = ret + tmp3;
} if (tmp4 != "零")
{
ret = ret + tmp4 ;
}
if (ret[0] == '零') //若第一个字符是'零',则去掉
ret = ret.Substring(1);
if (ret[ret.Length - 1] == '零') //若最后一个字符是'零',则去掉
ret = ret.Substring(0,ret.Length - 1); return ret + strDW; //加上本单元的单位
}
/// <summary>
/// 单个数字转为大写
/// </summary>
/// <param name="c">小写阿拉伯数字 0---9</param>
/// <returns>大写数字</returns>
private string getint(char c)
{
string str = "";
switch ( c )
{
case '0':
str = "零";
break;
case '1':
str = "壹";
break;
case '2':
str = "贰";
break;
case '3':
str = "叁";
break;
case '4':
str = "肆";
break;
case '5':
str = "伍";
break;
case '6':
str = "陆";
break;
case '7':
str = "柒";
break;
case '8':
str = "拐";
break;
case '9':
str = "玖";
break;
}
return str;
}
主要是判断语句比较复杂,有些情况不知道怎么处理
{
#region 数值大写
private const string Num1 = "壹";
private const string Num2 = "贰";
private const string Num3 = "叁";
private const string Num4 = "肆";
private const string Num5 = "伍";
private const string Num6 = "陆";
private const string Num7 = "柒";
private const string Num8 = "捌";
private const string Num9 = "玖";
private const string Num0 = "零"; private const string NumShi = "拾";
private const string NumBai = "佰";
private const string NumQian = "仟";
private const string NumWan = "萬";
private const string NumYi = "亿"; private const string Zheng = "整";
private const string Yuan = "元";
private const string Jiao = "角";
private const string Fen = "分"; #endregion
/// <summary>
/// 根据数字生成相应的大写型字符串
/// </summary>
public static string GenerateDaXieNum( decimal dec )
{
try
{
string sign = "";
if ( dec < 0 )
{
sign = "负";
dec = 0 - dec;
} long lng = Convert.ToInt64( dec );
if ( lng > dec )
lng --;
return sign + GenerateDaXieLng( lng ) + Yuan + GenerateDaXiePoint( dec - lng );
}
catch ( System.Exception ex )
{
throw ex;
}
} #region 获取整数部分大写
/// <summary>
/// 根据一个整数生成相应大写
/// </summary>
private static string GenerateDaXieLng( long lng )
{
if ( lng >= 100000000 )
return GenerateDaXieLng( lng / 100000000 ) + NumYi + ( ( lng - lng / 100000000 * 100000000 ) < 10000000 && ( lng - lng / 100000000 * 100000000 ) != 0 ? Num0 : "" ) + GenerateDaXieLng( lng - lng / 100000000 * 100000000 );
else if ( lng >= 10000 )
return GenerateDaXieLng( lng / 10000 ) + NumWan + ( ( lng - lng / 10000 * 10000 ) < 1000 && ( lng - lng / 10000 * 10000 ) != 0 ? Num0 : "" ) + GenerateDaXieLng( lng - lng / 10000 * 10000 );
else if ( lng >= 1000 )
return GenerateDaXieLng( lng / 1000 ) + NumQian + ( ( lng - lng / 1000 * 1000 ) < 100 && ( lng - lng / 1000 * 1000 ) != 0 ? Num0 : "" ) + GenerateDaXieLng( lng - lng / 1000 * 1000 );
else if ( lng >= 100 )
return GenerateDaXieLng( lng / 100 ) + NumBai + ( ( lng - lng / 100 * 100 ) < 10 && ( lng - lng / 100 * 100 ) != 0 ? Num0 : "" ) + GenerateDaXieLng( lng - lng / 100 * 100 );
else if ( lng >= 10 )
return GenerateDaXieLng( lng / 10 ) + NumShi + GenerateDaXieLng( lng - lng / 10 * 10 );
else if ( lng > 0 )
return DaXie(lng);
else
return ""; }
#endregion #region 获取小数部分大写
/// <summary>
/// 获取小数部分大写
/// </summary>
private static string GenerateDaXiePoint( decimal dec )
{
if ( dec == 0 ) return Zheng;
string str = dec.ToString();
str = str.Substring( str.IndexOf(".") +1 ); return DaXie( Convert.ToInt64( str.Substring( 0,1 ) ) ) + Jiao + DaXie( Convert.ToInt64( str.Substring( 1,1 ) ) ) + Fen ;
}
#endregion #region 获取单个数对应的大写
/// <summary>
/// 获取单个数对应的大写
/// </summary>
private static string DaXie( long i )
{
switch (i)
{
case 9:
return Num9;
case 8:
return Num8;
case 7:
return Num7;
case 6:
return Num6;
case 5:
return Num5;
case 4:
return Num4;
case 3:
return Num3;
case 2:
return Num2;
case 1:
return Num1;
default:
return Num0;
}
}
#endregion }
http://www.vckbase.com/bbs/prime/viewprime.asp?id=576
// 货币金额大写转换库 Money2String.dll// 静态中文转换方法 String GetCnString(String MoneyString)
// 最大转化金额 9999999999999999.99 (16位整数位,2位小数位)
// 方法返回值 转换成功则返回非零长字串,否则返回零长字串// 静态英文转换方法 String GetEnString(String MoneyString)
// 最大转化金额 999999999999999.99 (15位整数位,2位小数位)
// 方法返回值 转换成功则返回非零长字串,否则返回零长字串
// 程序设计 xlFancy 版本 2003.03.18.22 - 2003.04.09
// 邮箱地址 [email protected]
因为亿一般都是我门用到的最大位数了.这样处理好象比较麻烦.从下往上取怎么样呢?
这里就不说角很分了,问题类似
可以用for循环来取
可以在循环中替换成中文,我这里就不替换了
public string My = 10000000
public string myString = null;public static main()
{
if(My.Length<9)
myString = "";
MyTest(My);
//输出myString
else //假设位数小于18,不考虑更大的情况
{
myString = "";
MyTest(My.Substring(0,My.Length-9));
myString += "亿"
MyTest(My.Substring(My.Length-9,9));
//输出myString
}
}void MyTest(string My)
{
int len = My.Length;
for(int i = 0;i<len ;i++)
{
switch(i)
{
case 0:
myString = My.Substring(len - i -1,1) + "员" + myString ;
break;
case 1:
myString = My.Substring(len - i -1,1) + "拾"+ myString ;
break;
case 2:
myString = My.Substring(len - i -1,1) + "佰"+ myString ;
break;
case 3:
myString = My.Substring(len - i -1,1) + "仟"+ myString ;
break;
case 4:
myString = My.Substring(len - i -1,1) + "萬"+ myString ;
break;
case 5:
return MyTest(My.Substring(0,len - i));
break;
}
}
}以上代码手写,出现错误,修改一下
return GenerateDaXieLng(lng/10000) + NumWan + ((lng - lng / 10000 * 10000 ) < 1000 && ( lng - lng / 10000 * 10000 ) != 0 ? Num0 : "" ) + GenerateDaXieLng( lng - lng / 10000 * 10000 ); 是什么意思啊? 还有 string je = d.ToString("####.00");
if (je.Length > 15)
return "";
je = new String('0',15 - je.Length) + je;//若小于15位长,前面补0
中 string je = d.ToString("####.00");是输出格式吗?
je = new String('0',15 - je.Length) + je;为什么小于15位长,前面要补0?
return GenerateDaXieLng(lng/10000) + NumWan + ((lng - lng / 10000 * 10000 ) < 1000 && ( lng - lng / 10000 * 10000 ) != 0 ? Num0 : "" ) + GenerateDaXieLng( lng - lng / 10000 * 10000 ); 是什么意思啊? 还有 string je = d.ToString("####.00");
if (je.Length > 15)
return "";
je = new String('0',15 - je.Length) + je;//若小于15位长,前面补0
中 string je = d.ToString("####.00");是输出格式吗?
je = new String('0',15 - je.Length) + je;为什么小于15位长,前面要补0?
((lng - lng / 10000 * 10000 ) < 1000 && ( lng - lng / 10000 * 10000 ) != 0 ? Num0 : "" ) 判断万以下值是否大于1000(千位是否为零),小于1000加一个“零”
GenerateDaXieLng( lng - lng / 10000 * 10000 ); 得到 N千
if (je.Length > 15)
return "";
je = new String('0',15 - je.Length) + je;//若小于15位长,前面补0 中 string je = d.ToString("####.00"); 是输出格式吗?
je = new String('0',15 - je.Length) + je; 为什么小于15位长,前面要补0?
namespace Skyiv.Util
{
using System.Text;
class Test
{
static void Main()
{
for (;;)
{
System.Console.Write("金额: ");
string s = System.Console.ReadLine();
decimal m;
try { m = decimal.Parse(s); }
catch { break; }
System.Console.WriteLine("大写: " + new Money(m));
}
}
}
// 该类重载的 ToString() 方法返回的是大写金额字符串
class Money
{
public string Yuan = "元"; // “元”,可以改为“圆”、“卢布”之类
public string Jiao = "角"; // “角”,可以改为“拾”
public string Fen = "分"; // “分”,可以改为“美分”之类
static string Digit = "零壹贰叁肆伍陆柒捌玖"; // 大写数字
bool isAllZero = true; // 片段内是否全零
bool isPreZero = true; // 低一位数字是否是零
bool Overflow = false; // 溢出标志
long money100; // 金额*100,即以“分”为单位的金额
long value; // money100的绝对值
StringBuilder sb = new StringBuilder(); // 大写金额字符串,逆序
// 只读属性: "零元"
public string ZeroString
{
get { return Digit[0] + Yuan; }
}
// 构造函数
public Money(decimal money)
{
try { money100 = (long)(money * 100m); }
catch { Overflow = true; }
if (money100 == long.MinValue) Overflow = true;
}
// 重载 ToString() 方法,返回大写金额字符串
public override string ToString()
{
if (Overflow) return "金额超出范围";
if (money100 == 0) return ZeroString;
string [] Unit = { Yuan, "万", "亿", "万", "亿亿" };
value = System.Math.Abs(money100);
ParseSection(true);
for (int i = 0; i < Unit.Length && value > 0; i++)
{
if (isPreZero && !isAllZero) sb.Append(Digit[0]);
if (i == 4 && sb.ToString().EndsWith(Unit[2]))
sb.Remove(sb.Length - Unit[2].Length, Unit[2].Length);
sb.Append(Unit[i]);
ParseSection(false);
if ((i % 2) == 1 && isAllZero)
sb.Remove(sb.Length - Unit[i].Length, Unit[i].Length);
}
if (money100 < 0) sb.Append("负");
return Reverse();
}
// 解析“片段”: “角分(2位)”或“万以内的一段(4位)”
void ParseSection(bool isJiaoFen)
{
string [] Unit = isJiaoFen ?
new string [] { Fen, Jiao } :
new string [] { "", "拾", "佰", "仟" };
isAllZero = true;
for (int i = 0; i < Unit.Length && value > 0; i++)
{
int d = (int)(value % 10);
if (d != 0)
{
if (isPreZero && !isAllZero) sb.Append(Digit[0]);
sb.AppendFormat("{0}{1}", Unit[i], Digit[d]);
isAllZero = false;
}
isPreZero = (d == 0);
value /= 10;
}
}
// 反转字符串
string Reverse()
{
StringBuilder sbReversed = new StringBuilder();
for (int i = sb.Length - 1; i >= 0; i--)
sbReversed.Append(sb[i]);
return sbReversed.ToString();
}
}
}