public
Last active

Convert a text representing a number to a currency word version.

  • Download Gist
gistfile1.cs
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
public static class NumberWordConverter
{
#region Lookups
 
private static readonly Dictionary<char, string> units = new Dictionary<char, string>()
{
{'0', ""},
{'1', " One"},
{'2', " Two"},
{'3', " Three"},
{'4', " Four"},
{'5', " Five"},
{'6', " Six"},
{'7', " Seven"},
{'8', " Eight"},
{'9', " Nine"},
};
 
private static readonly Dictionary<char, string> tens = new Dictionary<char, string>()
{
{'0', ""},
{'1', " Ten"},
{'2', " Twenty"},
{'3', " Thirty"},
{'4', " Forty"},
{'5', " Fifty"},
{'6', " Sixty"},
{'7', " Seventy"},
{'8', " Eighty"},
{'9', " Ninety"},
};
 
private static readonly Dictionary<char, string> teens = new Dictionary<char, string>()
{
{'0', " Ten"},
{'1', " Eleven"},
{'2', " Twelve"},
{'3', " Thirteen"},
{'4', " Fourteen"},
{'5', " Fiveteen"},
{'6', " Sixteen"},
{'7', " Seventeen"},
{'8', " Eighteen"},
{'9', " Nineteen"},
};
 
private static readonly string[] numberScales = new string[]
{
"",
" Thousand",
" Million",
" Billion",
" Trillion",
" Quadrillion",
" Quintillion",
" Sextillion",
" Septillion"
};
 
#endregion
 
public static string ToCurrencyWords(this string text, string major = "Dollars", string minor = "Cents", int minorSize = 2)
{
string[] parts = (text + ".00").Split('.'); // Forces all numbers to #.00 format.
// If supplied number contained a fraction, then the split array now contain
// 3 elements so will ignore our extra addition.
 
// Force fractional parts to 1 extra decimal places then round away from zero
parts[1] = Math
.Round(int.Parse(parts[1].PadRight(minorSize + 1, '0').Substring(0, minorSize + 1)) / 10d, MidpointRounding.AwayFromZero)
.ToString(CultureInfo.InvariantCulture);
 
string majorText = parts[0].ToNumber(major);
string minorText = parts[1].ToNumber(minor);
 
return majorText
+ (majorText.Length > 0 && minorText.Length > 0 ? " and " : "")
+ minorText;
}
 
public static string ToNumber(this string text, string postFix)
{
int length = text.Length + (3 - text.Length%3)%3;
 
Stack<char> chars = new Stack<char>(text.PadLeft(length, '0').ToCharArray());
Queue<string> modifiers = new Queue<string>(numberScales);
 
string result = string.Empty;
while (chars.Count > 0)
{
 
result = ConvertTriad(chars.Pop(), chars.Pop(), chars.Pop(), modifiers.Dequeue(), chars.Count > 0) + result;
}
 
return (string.IsNullOrWhiteSpace(result) ? string.Empty : result.Trim() + " " + postFix);
}
 
private static string ConvertTriad(char unit, char ten, char hundred, string modifier, bool hasMore)
{
string result = "";
string tempModifier = string.Empty; // In the case all 3 chars are '0' we skip this level
if (hundred != '0')
{
result = units[hundred] + " hundred";
tempModifier = modifier; // Have a hundred number, restore the modifier in case no tens or units
}
 
if (ten == '0' && unit == '0')
return result + tempModifier;
 
 
if (!string.IsNullOrEmpty(result) || hasMore)
result += " and";
 
return result + ((ten == '1') ? teens[unit] : tens[ten] + units[unit]) + modifier;
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.