I needed to add the ability to print checks from an application I was writing and a portion of that process included converting a number into its english text representation (ie $25.00 to Twenty Five Dollars). I thought that the .Net Framework would have some sort of conversion function built in but I could not find one so I went to the internet and found a pretty good one here. Firstly, I found a bug in the code when converting anything that was a multiple of 100,000; it wouldn’t include the ‘Thousand’ in the resulting string and thus converting 100,000 would result in ‘One Hundred’. I fixed that pretty quickly but it still wasn’t exactly what I needed as it didn’t handle decimal or floating point numbers. I wrote another method that utilized it but handeled decimal numbers.
public static string NumberToCurrencyText(decimal number, MidpointRounding midpointRounding) { // Round the value just in case the decimal value is longer than two digits number = decimal.Round(number, 2, midpointRounding); string wordNumber = string.Empty; // Divide the number into the whole and fractional part strings string[] arrNumber = number.ToString().Split('.'); // Get the whole number text long wholePart = long.Parse(arrNumber[0]); string strWholePart = NumberToText(wholePart); // For amounts of zero dollars show 'No Dollars...' instead of 'Zero Dollars...' wordNumber = (wholePart == 0 ? "No" : strWholePart) + (wholePart == 1 ? " Dollar and " : " Dollars and "); // If the array has more than one element then there is a fractional part otherwise there isn't // just add 'No Cents' to the end if (arrNumber.Length > 1) { // If the length of the fractional element is only 1, add a 0 so that the text returned isn't, // 'One', 'Two', etc but 'Ten', 'Twenty', etc. long fractionPart = long.Parse((arrNumber[1].Length == 1 ? arrNumber[1] + "0" : arrNumber[1])); string strFarctionPart = NumberToText(fractionPart); wordNumber += (fractionPart == 0 ? " No" : strFarctionPart) + (fractionPart == 1 ? " Cent" : " Cents"); } else wordNumber += "No Cents"; return wordNumber; } public static string NumberToText(long number) { StringBuilder wordNumber = new StringBuilder(); string[] powers = new string[] { "Thousand ", "Million ", "Billion " }; string[] tens = new string[] { "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }; string[] ones = new string[] { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" }; if (number == 0) { return "Zero"; } if (number < 0) { wordNumber.Append("Negative "); number = -number; } long[] groupedNumber = new long[] { 0, 0, 0, 0 }; int groupIndex = 0; while (number > 0) { groupedNumber[groupIndex++] = number % 1000; number /= 1000; } for (int i = 3; i >= 0; i--) { long group = groupedNumber[i]; if (group >= 100) { wordNumber.Append(ones[group / 100 - 1] + " Hundred "); group %= 100; if (group == 0 && i > 0) wordNumber.Append(powers[i - 1]); } if (group >= 20) { if ((group % 10) != 0) wordNumber.Append(tens[group / 10 - 2] + " " + ones[group % 10 - 1] + " "); else wordNumber.Append(tens[group / 10 - 2] + " "); } else if (group > 0) wordNumber.Append(ones[group - 1] + " "); if (group != 0 && i > 0) wordNumber.Append(powers[i - 1]); } return wordNumber.ToString().Trim(); } }
I have tested this quite a bit but I make no guarantees.