Skip to content

Instantly share code, notes, and snippets.

@slaneyrw
Last active December 12, 2015 05:28
Show Gist options
  • Save slaneyrw/4721445 to your computer and use it in GitHub Desktop.
Save slaneyrw/4721445 to your computer and use it in GitHub Desktop.
Convert a text representing a number to a currency word version.
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;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment