All articles| All Pictures| All Softwares| All Video| Go home page| Write articles| Upload pictures

Reading number is top 10 articles
实现ASP.NET生成随机密码功能_[Asp.Net教程]
C++流的概念[一]
新手:什么是PHP?网站开发为什么选择PHP?_php资料_编程技术
提高PHP程序运行效率的四个小方法_php资料_编程技术
向普通人加密,用PHP程序保护数据_php资料_编程技术
.net发送邮件的一些技巧_.net资料_编程技术
VC++大数据量绘图时无闪烁刷屏技术实现_[Asp.Net教程]
c#中DateTime函数的各种显示效果_[Asp.Net教程]
在ASP.NET中自动给URL地址加上超链接修正版_[Asp.Net教程]
网页技巧:如何在网页上实现音乐播放?_JavaScript技术_编程技术
Reading number is top 10 pictures
Nine school beauty star those gossip matters
深圳的风光
Soldier saw beauty after the reaction
粉红蕾丝的美女
这才叫绝色美女2
俄罗斯台球天后惊艳魅惑1
可爱的小动物
Plump, too plump!1
Born After 90 Beijing sports university campus flower photos4
Startling Russian girl blind date scene3
Download software ranking
Tram sex maniac 2 (H) rar bag11
apache-tomcat-6.0.33
C#程序员参考手册
Ashlynn Video4
Boxer vs Yellow2
I'm come from Beijing1
Jinling thirteen stock
Unix video tutorial13
The king of fighters 97(Mobile phone games-apk)
Unix video tutorial20
delv published in(发表于) 2014/1/10 6:29:21 Edit(编辑)
C#纯数学方法递归实现货币数字转换中文_[Asp.Net教程]

C#纯数学方法递归实现货币数字转换中文_[Asp.Net教程]

C#纯数学方法递归实现货币数字转换中文_[Asp.Net教程]


一个货币数字转换中文的算法,注意:本文中的算法支持小于1023 (也就是9999亿兆)货币数字转化。
  货币中文说明: 在说明代码之前,首先让我们回顾一下货币的读法。


  10020002.23 读为 壹仟零贰万零贰元贰角叁分
  1020 读为 壹仟零贰拾元整。
  100000 读为 拾万元整
  0.13 读为 壹角叁分


  代码:


测试工程
static void Main(string[] args)
{


Console.WriteLine("请输入金额");
string inputNum = Console.ReadLine();
while (inputNum != "exit")
{


//货币数字转化类
NumCast nc = new NumCast();



if (nc.IsValidated(inputNum))
{
try
{
string chineseCharacter = nc.ConvertToChinese(inputNum);
Console.WriteLine(chineseCharacter);
}
catch (Exception er)
{
Console.WriteLine(er.Message);
}
}
else
{
Console.WriteLine("不合法的数字或格式");
}


Console.WriteLine("\n请输入金额");
inputNum = Console.ReadLine();


}
Console.ReadLine();
}


测试结果如下:


货币转化类(NumCast类)功能介绍


1 常量的规定
///


/// 数位
///

public enum NumLevel { Cent, Chiao, Yuan, Ten, Hundred, Thousand, TenThousand, hundredMillon, Trillion };


///


/// 数位的指数
///

private int[] NumLevelExponent = new int[] { -2, -1, 0, 1, 2, 3, 4, 8, 12 };


///


/// 数位的中文字符
///

private string[] NumLeverChineseSign = new string[] { "分", "角", "元", "拾", "佰", "仟", "万", "亿", "兆" };


///


/// 大写字符
///

private string[] NumChineseCharacter = new string[] {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};



///


/// 整(当没有 角分 时)
///


private const string EndOfInt = "整";


2:数字合法性验证,采用正则表达式验证
///


/// 正则表达验证数字是否合法
///

///
///
public bool IsValidated(T Num)
{
Regex reg = new Regex(@"^(([0])|([1-9]\d{0,23}))(\.\d{1,2})?");
if (reg.IsMatch(Num.ToString()))
{
return true;


}
return false;
}



3: 获取数位 例如 1000的数位为 NumLevel.Thousand


///


/// 获取数字的数位 使用log
///

///
///
private NumLevel GetNumLevel(double Num)
{
double numLevelLength;
NumLevel NLvl = new NumLevel();
if (Num > 0)
{
numLevelLength = Math.Floor(Math.Log10(Num));
for (int i = NumLevelExponent.Length - 1; i >= 0; i--)
{
if (numLevelLength >= NumLevelExponent[i])
{
NLvl = (NumLevel)i;
break;
}
}
}
else
{
NLvl = NumLevel.Yuan;
}
return NLvl;


}


4:判断数字之间是否有跳位,也就是中文中间是否要加零,例如1020 就应该加零。
///


/// 是否跳位
///

///
private bool IsDumpLevel(double Num)
{
if (Num > 0)
{
NumLevel? currentLevel = GetNumLevel(Num);
NumLevel? nextLevel = null;
int numExponent = this.NumLevelExponent[(int)currentLevel];


double postfixNun = Math.Round(Num % (Math.Pow(10, numExponent)),2);
if(postfixNun> 0)
nextLevel = GetNumLevel(postfixNun);
if (currentLevel != null && nextLevel != null)
{
if (currentLevel > nextLevel + 1)
{
return true;
}
}
}
return false;


}


5 把长数字分割为两个较小的数字数组,例如把9999亿兆,分割为9999亿和0兆,


因为计算机不支持过长的数字。
///


/// 是否大于兆,如果大于就把字符串分为两部分,
/// 一部分是兆以前的数字
/// 另一部分是兆以后的数字
///

///
///
private bool IsBigThanTillion(string Num)
{
bool isBig = false;
if (Num.IndexOf('.') != -1)
{
//如果大于兆
if (Num.IndexOf('.') > NumLevelExponent[(int)NumLevel.Trillion])
{
isBig = true;
}
}
else
{
//如果大于兆
if (Num.Length > NumLevelExponent[(int)NumLevel.Trillion])
{
isBig = true;
}
}
return isBig;
}


///


/// 把数字字符串由‘兆’分开两个
///

///
private double[] SplitNum(string Num)
{
//兆的开始位
double[] TillionLevelNums = new double[2];
int trillionLevelLength;
if (Num.IndexOf('.') == -1)
trillionLevelLength = Num.Length - NumLevelExponent[(int)NumLevel.Trillion];
else
trillionLevelLength = Num.IndexOf('.') - NumLevelExponent[(int)NumLevel.Trillion];
//兆以上的数字
TillionLevelNums[0] = Convert.ToDouble(Num.Substring(0, trillionLevelLength));
//兆以下的数字
TillionLevelNums[1] = Convert.ToDouble(Num.Substring(trillionLevelLength ));
return TillionLevelNums;
}


6 是否以“壹拾”开头,如果是就可以把它变为“拾”
bool isStartOfTen = false;
while (Num >=10)
{
if (Num == 10)
{
isStartOfTen = true;
break;
}
//Num的数位

NumLevel currentLevel = GetNumLevel(Num);


int numExponent = this.NumLevelExponent[(int)currentLevel];
Num = Convert.ToInt32(Math.Floor(Num / Math.Pow(10, numExponent)));
if (currentLevel == NumLevel.Ten && Num == 1)
{
isStartOfTen = true;
break;
}
}
return isStartOfTen;



7 合并大于兆连个数组转化成的货币字符串


///


/// 合并分开的数组中文货币字符
///

///
///
private string ContactNumChinese(double[] tillionNums)
{
string uptillionStr = CalculateChineseSign(tillionNums[0], NumLevel.Trillion, true, IsStartOfTen(tillionNums[0]));
string downtrillionStr = CalculateChineseSign(tillionNums[1], null, true,false);
string chineseCharactor = string.Empty;
//分开后的字符是否有跳位
if (GetNumLevel(tillionNums[1] * 10) == NumLevel.Trillion)
{
chineseCharactor = uptillionStr + NumLeverChineseSign[(int)NumLevel.Trillion] + downtrillionStr;
}
else
{
chineseCharactor = uptillionStr + NumLeverChineseSign[(int)NumLevel.Trillion];
if (downtrillionStr != "零元整")
{
chineseCharactor += NumChineseCharacter[0] + downtrillionStr;
}
else
{
chineseCharactor += "元整";
}
}
return chineseCharactor;


}


8:递归计算货币数字的中文
///


/// 计算中文字符串
///

/// 数字
/// 数位级别 比如1000万的 数位级别为万
/// 是否以‘壹拾’开头
/// 中文大写
public string CalculateChineseSign(double Num, NumLevel? NL ,bool IsDump,bool IsExceptTen)
{
Num = Math.Round(Num, 2);
bool isDump = false;
//Num的数位
NumLevel? currentLevel = GetNumLevel(Num);
int numExponent = this.NumLevelExponent[(int)currentLevel];


string Result = string.Empty;


//整除后的结果
int prefixNum;
//余数 当为小数的时候 分子分母各乘100
double postfixNun ;
if (Num >= 1)
{
prefixNum = Convert.ToInt32(Math.Floor(Num / Math.Pow(10, numExponent)));
postfixNun = Math.Round(Num % (Math.Pow(10, numExponent)), 2);
}
else
{
prefixNum = Convert.ToInt32(Math.Floor(Num*100 / Math.Pow(10, numExponent+2)));
postfixNun = Math.Round(Num * 100 % (Math.Pow(10, numExponent + 2)), 2);
postfixNun *= 0.01;
}


if (prefixNum < 10 )
{
//避免以‘壹拾’开头
if (!(NumChineseCharacter[(int)prefixNum] == NumChineseCharacter[1]
&& currentLevel == NumLevel.Ten && IsExceptTen))
{
Result += NumChineseCharacter[(int)prefixNum];
}
else
{
IsExceptTen = false;
}
//加上单位
if (currentLevel == NumLevel.Yuan )
{
////当为 “元” 位不为零时 加“元”。
if (NL == null)
{
Result += NumLeverChineseSign[(int)currentLevel];
//当小数点后为零时 加 "整"
if (postfixNun == 0)
{
Result += EndOfInt;
}
}
}
else
{
Result += NumLeverChineseSign[(int)currentLevel];
}
//当真正的个位为零时 加上“元”
if (NL == null && postfixNun < 1 && currentLevel > NumLevel.Yuan && postfixNun > 0)
{
Result += NumLeverChineseSign[(int)NumLevel.Yuan];


}



}
else
{
//当 前缀数字未被除尽时, 递归下去
NumLevel? NextNL = null;
if ((int)currentLevel >= (int)(NumLevel.TenThousand))
NextNL = currentLevel;


Result += CalculateChineseSign((double)prefixNum, NextNL, isDump, IsExceptTen);
if ((int)currentLevel >= (int)(NumLevel.TenThousand))
{
Result += NumLeverChineseSign[(int)currentLevel];
}
}


//是否跳位
// 判断是否加零, 比如302 就要给三百 后面加零,变为 三百零二。
if (IsDumpLevel(Num))
{
Result += NumChineseCharacter[0];
isDump = true;


}


//余数是否需要递归
if (postfixNun > 0)
{
Result += CalculateChineseSign(postfixNun, NL, isDump, false);
}
else if (postfixNun == 0 && currentLevel > NumLevel.Yuan )
{
//当数字是以零元结尾的加上 元整 比如1000000一百万元整
if (NL == null)
{
Result += NumLeverChineseSign[(int)NumLevel.Yuan];
Result += EndOfInt;
}
}


return Result;
}



9:外部调用的转换方法。


///


/// 外部调用的转换方法
///

///
///

public string ConvertToChinese(string Num)
{


if (!IsValidated(Num))
{
throw new OverflowException("数值格式不正确,请输入小于9999亿兆的数字且最多精确的分的金额!");
}
string chineseCharactor = string.Empty;
if (IsBigThanTillion(Num))
{
double[] tillionNums = SplitNum(Num);
chineseCharactor = ContactNumChinese(tillionNums);
}
else
{
double dNum = Convert.ToDouble(Num);
chineseCharactor = CalculateChineseSign(dNum, null, true, IsStartOfTen(dNum));
}
return chineseCharactor;
}


  小结:


  个人认为程序的灵魂是算法,大到一个系统中的业务逻辑,小到一个货币数字转中文的算法,处处都体现一种逻辑思想。


  是否能把需求抽象成一个好的数学模型,直接关系到程序的实现的复杂度和稳定性。在一些常用功能中想些不一样的算法,对我们开拓思路很有帮助。


来源:http://www.knowsky.com/343783.html







添加到del.icio.us 添加到新浪ViVi 添加到百度搜藏 添加到POCO网摘 添加到天天网摘365Key 添加到和讯网摘 添加到天极网摘 添加到黑米书签 添加到QQ书签 添加到雅虎收藏 添加到奇客发现 diigo it 添加到饭否 添加到飞豆订阅 添加到抓虾收藏 添加到鲜果订阅 digg it 貼到funP 添加到有道阅读 Live Favorites 添加到Newsvine 打印本页 用Email发送本页 在Facebook上分享


Disclaimer Privacy Policy About us Site Map

If you have any requirements, please contact webmaster。(如果有什么要求,请联系站长)
Copyright ©2011-
uuhomepage.com, Inc. All rights reserved.