C recursively realizes the Chinese function of currency digital conversion based on pure mathematical method
- 2021-12-09 09:45:22
- OfStack
In this paper, C # recursively realizes the function of converting currency numbers into Chinese based on pure mathematics. Share it for your reference, as follows:
Recently, due to the project reasons, need to write a currency digital conversion Chinese algorithm, first in the net to find 1, the results found that no one column is replaced by (Replace) to achieve, so want to write another algorithm; Because I was born in mathematics, I realized it by pure mathematics.
Note: The algorithm in this paper supports digital conversion of currencies less than 1023 (that is, 999.9 billion megabytes).
Chinese description of currency: Before explaining the code, let's review the pronunciation of currency.
On February 23, 10020002.23, it was read as 10,20,200 yuan and 23 cents
1020 is read as one thousand and twenty yuan only.
100,000 yuan is read as 100,000 yuan only
0.13 is read as a quarter
Code:
Test engineering
static void Main(string[] args)
{
Console.WriteLine(" Please enter an amount ");
string inputNum = Console.ReadLine();
while (inputNum != "exit")
{
// Currency digital conversion class
NumCast nc = new NumCast();
if (nc.IsValidated<string>(inputNum))
{
try
{
string chineseCharacter = nc.ConvertToChinese(inputNum);
Console.WriteLine(chineseCharacter);
}
catch (Exception er)
{
Console.WriteLine(er.Message);
}
}
else
{
Console.WriteLine(" Illegal numbers or formats ");
}
Console.WriteLine("\n Please enter an amount ");
inputNum = Console.ReadLine();
}
Console.ReadLine();
}
Introduction to the functions of currency conversion class (NumCast class)
1. Constant provisions
/// <summary>
/// Digital
/// </summary>
public enum NumLevel { Cent, Chiao, Yuan, Ten, Hundred, Thousand, TenThousand, hundredMillon, Trillion };
/// <summary>
/// Exponent of digits
/// </summary>
private int[] NumLevelExponent = new int[] { -2, -1, 0, 1, 2, 3, 4, 8, 12 };
/// <summary>
/// Digital Chinese characters
/// </summary>
private string[] NumLeverChineseSign = new string[] { " Points ", " Angle ", " Yuan ", " Pick up ", " Bai ", " Thousands ", " Ten thousand ", " Billion ", " Mega " };
/// <summary>
/// Uppercase character
/// </summary>
private string[] NumChineseCharacter = new string[] {" Zero "," One "," 2 "," 3 "," Four "," Wu "," Land "," Qi "," Eight "," Nine "};
/// <summary>
/// Whole ( When there is no Angular fraction Hour )
/// </summary>
private const string EndOfInt = " Whole ";
2. Validation of digital validity, using regular expression verification
/// <summary>
/// Regular expression verifies whether numbers are legal
/// </summary>
/// <param name="Num"></param>
/// <returns></returns>
public bool IsValidated<T>(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. Get digits for example, the digits of 1000 are NumLevel. Thousand
/// <summary>
/// Gets the digital usage of a number log
/// </summary>
/// <param name="Num"></param>
/// <returns></returns>
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. Judge whether there is a jump bit between numbers, that is, whether zero should be added in the middle of Chinese, for example, 1020 should be added with zero.
/// <summary>
/// Whether to skip bits or not
/// </summary>
/// <returns></returns>
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. Split long numbers into two smaller arrays of numbers, such as 999.9 billion megabytes, 999.9 billion megabytes and 0 megabytes, because computers do not support excessively long numbers.
/// <summary>
/// Whether it is greater than megabytes, if it is greater, divide the string into two parts,
/// 1 Part of it is a number before megabytes
/// Another 1 Part of it is the number after megabytes
/// </summary>
/// <param name="Num"></param>
/// <returns></returns>
private bool IsBigThanTillion(string Num)
{
bool isBig = false;
if (Num.IndexOf('.') != -1)
{
// If it is greater than megabytes
if (Num.IndexOf('.') > NumLevelExponent[(int)NumLevel.Trillion])
{
isBig = true;
}
}
else
{
// If it is greater than megabytes
if (Num.Length > NumLevelExponent[(int)NumLevel.Trillion])
{
isBig = true;
}
}
return isBig;
}
/// <summary>
/// Change the number string from'megabytes' ' Split two
/// </summary>
/// <returns></returns>
private double[] SplitNum(string Num)
{
// Start bit of megabit
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];
// Figures above megabytes
TillionLevelNums[0] = Convert.ToDouble(Num.Substring(0, trillionLevelLength));
// Figures below megabytes
TillionLevelNums[1] = Convert.ToDouble(Num.Substring(trillionLevelLength ));
return TillionLevelNums;
}
6. Do you start with "ten"? If so, you can change it into "ten"
bool isStartOfTen = false;
while (Num >=10)
{
if (Num == 10)
{
isStartOfTen = true;
break;
}
//Num Digit of
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. Merge currency strings converted from arrays larger than megabytes
/// <summary>
/// Merge separate arrays of Chinese currency characters
/// </summary>
/// <param name="tillionNums"></param>
/// <returns></returns>
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;
// Does the separated character have a skip bit
if (GetNumLevel(tillionNums[1] * 10) == NumLevel.Trillion)
{
chineseCharactor = uptillionStr + NumLeverChineseSign[(int)NumLevel.Trillion] + downtrillionStr;
}
else
{
chineseCharactor = uptillionStr + NumLeverChineseSign[(int)NumLevel.Trillion];
if (downtrillionStr != " Zero integral ")
{
chineseCharactor += NumChineseCharacter[0] + downtrillionStr;
}
else
{
chineseCharactor += " Element integral ";
}
}
return chineseCharactor;
}
8. Chinese for recursive calculation of monetary numbers
/// <summary>
/// Calculate Chinese string
/// </summary>
/// <param name="Num"> Figures </param>
/// <param name="NL"> Digital level For example 1000 Ten thousand The digital level is ten thousand </param>
/// <param name="IsExceptTen"> Whether to use 'Ten Ten ' Beginning </param>
/// <returns> Chinese capitalization </returns>
public string CalculateChineseSign(double Num, NumLevel? NL ,bool IsDump,bool IsExceptTen)
{
Num = Math.Round(Num, 2);
bool isDump = false;
//Num Digit of
NumLevel? currentLevel = GetNumLevel(Num);
int numExponent = this.NumLevelExponent[(int)currentLevel];
string Result = string.Empty;
// The result of division
int prefixNum;
// Remainder When it is a decimal, Multiplication of numerator and denominator 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 )
{
// Avoid using 'One Hundred ' Beginning
if (!(NumChineseCharacter[(int)prefixNum] == NumChineseCharacter[1]
&& currentLevel == NumLevel.Ten && IsExceptTen))
{
Result += NumChineseCharacter[(int)prefixNum];
}
else
{
IsExceptTen = false;
}
// Plus units
if (currentLevel == NumLevel.Yuan )
{
//// When is "Yuan" When the bit is not zero Add "yuan".
if (NL == null)
{
Result += NumLeverChineseSign[(int)currentLevel];
// When zero after the decimal point Plus " Whole "
if (postfixNun == 0)
{
Result += EndOfInt;
}
}
}
else
{
Result += NumLeverChineseSign[(int)currentLevel];
}
// Add "yuan" when the real bit is zero
if (NL == null && postfixNun < 1 && currentLevel > NumLevel.Yuan && postfixNun > 0)
{
Result += NumLeverChineseSign[(int)NumLevel.Yuan];
}
}
else
{
// When When the prefix number is not completely divided, Recursive down
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];
}
}
// Whether to skip bits or not
// Judge whether to add zero, For example 302 Will be given 3 Hundred After that, add zero to become 3 100 2 .
if (IsDumpLevel(Num))
{
Result += NumChineseCharacter[0];
isDump = true;
}
// Does the remainder need recursion
if (postfixNun > 0)
{
Result += CalculateChineseSign(postfixNun, NL, isDump, false);
}
else if (postfixNun == 0 && currentLevel > NumLevel.Yuan )
{
// When the number ends in zero plus Element integral For example 10000001 Millions of dollars only
if (NL == null)
{
Result += NumLeverChineseSign[(int)NumLevel.Yuan];
Result += EndOfInt;
}
}
return Result;
}
9. Externally invoked conversion methods.
/// <summary>
/// Externally called conversion method
/// </summary>
/// <param name="Num"></param>
/// <returns></returns>
public string ConvertToChinese(string Num)
{
if (!IsValidated<string>(Num))
{
throw new OverflowException(" The numeric value format is incorrect, please enter less than 9999 Billion trillion figures and the most accurate points of the amount! ");
}
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;
}
Summary:
Personally, I think the soul of the program is algorithm, which is as large as the business logic in a system and as small as the algorithm of converting monetary numbers into Chinese, and embodies a kind of logic thought everywhere.
Whether the requirement can be abstracted into a good mathematical model is directly related to the complexity and stability of the program. Think of some different algorithms in some common functions, which is very helpful for us to open up ideas.
For more readers interested in C # related content, please check the topics on this site: "C # Mathematical Operation Skills Summary", "C # Form Operation Skills Summary", "C # Common Control Usage Tutorial", "C # Control Usage Summary", "C # Programming Thread Use Skills Summary", "C # Data Structure and Algorithm Tutorial", "C # Array Operation Skills Summary" and "C # Object-Oriented Programming Introduction Tutorial"
I hope this article is helpful to everyone's C # programming.