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.


Related articles: