#### [SOLVED] How can I convert an integer into its verbal representation?

By Malfist

Is there a library or a class/function that I can use to convert an integer to it's verbal representation?

Example input:

4,567,788`

Example output:

Four million, Five hundred sixty-seven thousand, seven hundred eighty-eight #### @Hannele 2013-11-26 17:46:04

Fully recursive version:

``````private static string[] ones = {
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen",
};

private static string[] tens = { "zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" };

private static string[] thous = { "hundred", "thousand", "million", "billion", "trillion", "quadrillion" };

private static string fmt_negative = "negative {0}";
private static string fmt_dollars_and_cents = "{0} dollars and {1} cents";
private static string fmt_tens_ones = "{0}-{1}"; // e.g. for twenty-one, thirty-two etc. You might want to use an en-dash or em-dash instead of a hyphen.
private static string fmt_large_small = "{0} {1}"; // stitches together the large and small part of a number, like "{three thousand} {five hundred forty two}"
private static string fmt_amount_scale = "{0} {1}"; // adds the scale to the number, e.g. "{three} {million}";

public static string ToWords(decimal number) {
if (number < 0)
return string.format(fmt_negative, ToWords(Math.Abs(number)));

int intPortion = (int)number;
int decPortion = (int)((number - intPortion) * (decimal) 100);

return string.Format(fmt_dollars_and_cents, ToWords(intPortion), ToWords(decPortion));
}

private static string ToWords(int number, string appendScale = "") {
string numString = "";
// if the number is less than one hundred, then we're mostly just pulling out constants from the ones and tens dictionaries
if (number < 100) {
if (number < 20)
numString = ones[number];
else {
numString = tens[number / 10];
if ((number % 10) > 0)
numString = string.Format(fmt_tens_ones, numString, ones[number % 10]);
}
} else {
int pow = 0; // we'll divide the number by pow to figure out the next chunk
string powStr = ""; // powStr will be the scale that we append to the string e.g. "hundred", "thousand", etc.

if (number < 1000) { // number is between 100 and 1000
pow = 100; // so we'll be dividing by one hundred
powStr = thous; // and appending the string "hundred"
} else { // find the scale of the number
// log will be 1, 2, 3 for 1_000, 1_000_000, 1_000_000_000, etc.
int log = (int)Math.Log(number, 1000);
// pow will be 1_000, 1_000_000, 1_000_000_000 etc.
pow = (int)Math.Pow(1000, log);
// powStr will be thousand, million, billion etc.
powStr = thous[log];
}

// we take the quotient and the remainder after dividing by pow, and call ToWords on each to handle cases like "{five thousand} {thirty two}" (curly brackets added for emphasis)
numString = string.Format(fmt_large_small, ToWords(number / pow, powStr), ToWords(number % pow)).Trim();
}

// and after all of this, if we were passed in a scale from above, we append it to the current number "{five} {thousand}"
return string.Format(fmt_amount_scale, numString, appendScale).Trim();
}
``````

Current works up to the (short scale) quadrillions. Additional support (for larger numbers, or for the long scale) can be added simply by changing the `thous` variable. #### @Marco Alves 2017-02-09 12:53:07

This is exactly what i needed. Thank you #### @Marvin Glenn Lacuna 2017-10-20 02:51:15

I was tasked to create a WEB API that converts numbers to words using C#.

Can be whole number or with decimal points in 48 hours time.

The call will be coming from a front-end application using Ajax Post method and return the converted result in the webpage.

I've publicly shared that project in the GitHub for reference: https://github.com/marvinglennlacuna/NumbersToWordsConverter.Api

With the following technical implementatation in placed:

1. MVC structured
2. API Controller
3. Service
4. Model
5. Error Handling
6. Unit Testing using MSTest
7. Code Coverage - 98%
8. Jquery

And with technical documentation about the following as well:

1. Purpose
2. Prerequisites
3. Functionl Requirements
4. Process Diagram and Output

**Result via Web Page (US-001) **

US-001 Convert Numbers to Words via web page process US-001 Convert Numbers to Words via web page output Result via Postman (US-002)

US-002 - Convert Numbers to Words via Postman process US-002 - Convert Numbers to Words via Postman output I think it's just worth sharing a working solution in the case you need it for reference in interview/code test/school or for fun only.

Cheers, Marvin #### @Chris Pratt 2017-07-08 01:21:36

I actually needed this for an app I'm working on, but wasn't happy with any of the solutions here. FYI, this solution takes advantage of C# 7.0's support for local functions. I also used the new digit separator to make the larger numbers more readable.

``````public static class NumberExtensions
{
private const string negativeWord = "negative";
private static readonly Dictionary<ulong, string> _wordMap = new Dictionary<ulong, string>
{
[1_000_000_000_000_000_000] = "quintillion",
[1_000_000_000_000] = "trillion",
[1_000_000_000] = "billion",
[1_000_000] = "million",
[1_000] = "thousand",
 = "hundred",
 = "ninety",
 = "eighty",
 = "seventy",
 = "sixty",
 = "fifty",
 = "forty",
 = "thirty",
 = "twenty",
 = "nineteen",
 = "eighteen",
 = "seventeen",
 = "sixteen",
 = "fifteen",
 = "fourteen",
 = "thirteen",
 = "twelve",
 = "eleven",
 = "ten",
 = "nine",
 = "eight",
 = "seven",
 = "six",
 = "five",
 = "four",
 = "three",
 = "two",
 = "one",
 = "zero"
};

public static string ToWords(this short num)
{
var words = ToWords((ulong)Math.Abs(num));
return num < 0 ? \$"{negativeWord} {words}" : words;
}

public static string ToWords(this ushort num)
{
}

public static string ToWords(this int num)
{
var words = ToWords((ulong)Math.Abs(num));
return num < 0 ? \$"{negativeWord} {words}" : words;
}

public static string ToWords(this uint num)
{
}

public static string ToWords(this long num)
{
var words = ToWords((ulong)Math.Abs(num));
return num < 0 ? \$"{negativeWord} {words}" : words;
}

public static string ToWords(this ulong num)
{
var sb = new StringBuilder();
var delimiter = String.Empty;

void AppendWords(ulong dividend)
{
void AppendDelimitedWord(ulong key)
{
sb.Append(delimiter);
sb.Append(_wordMap[key]);
delimiter = 20 <= key && key < 100 ? "-" : " ";
}

if (_wordMap.ContainsKey(dividend))
{
AppendDelimitedWord(dividend);
}
else
{
var divisor = _wordMap.First(m => m.Key <= dividend).Key;
var quotient = dividend / divisor;
var remainder = dividend % divisor;

if (quotient > 0 && divisor >= 100)
{
AppendWords(quotient);
}

AppendDelimitedWord(divisor);

if (remainder > 0)
{
AppendWords(remainder);
}
}
}

AppendWords(num);
return sb.ToString();
}
}
``````

The meat is in the last `ToWords` overload. #### @Xtian11 2017-06-01 15:12:41

Here is the spanish version:

``````        public static string numeroALetras(int number)
{
if (number == 0)
return "cero";

if (number < 0)
return "menos " + numeroALetras(Math.Abs(number));

string words = "";

if ((number / 1000000) > 0)
{
words += numeroALetras(number / 1000000) + " millón ";
number %= 1000000;
}

if ((number / 1000) > 0)
{
words += (number / 1000) == 1? "mil ": numeroALetras(number / 1000) + " mil ";
number %= 1000;
}
if ((number / 100) == 1)
{
if (number == 100)
words += "cien";
else words += (number / 100)> 1? numeroALetras(number / 100) + " ciento ":"ciento ";
number %= 100;
}
if ((number / 100) > 1)
{
var hundredMap = new[] {"","", "dosc", "tresc", "cuatroc", "quin", "seisc", "sietec", "ochoc", "novec" };
if (number > 199)
words += hundredMap[number/100] + "ientos ";
else {
words += numeroALetras(number / 100) + " ientos ";
}
number %= 100;
}

if (number > 0)
{
if (words != "")
words += " ";

var unitsMap = new[] { "cero", "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve", "diez", "once", "doce", "trece", "catorce", "quince", "dieciseis", "diecisiete", "dieciocho", "diecinueve", "veinte" };
var tensMap = new[] { "cero", "diez", "veinti", "treinta", "cuarenta", "cincuenta", "sesenta", "setenta", "ochenta", "noventa" };

if (number < 21)
words += unitsMap[number];
else
{
words += tensMap[number / 10];
if ((number % 10) > 0)
words += ((number % 10)>2?" y ": "") + unitsMap[number % 10];
}
}

return words;
}
`````` #### @Santhosh 2017-03-22 01:23:43

The following C# console app code will give accepts a monetary value in numbers up to 2 decimals and prints it in English. You can use it as a reference to achieve your results.

``` namespace ConsoleApplication2 { using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; class Program { static void Main(string[] args) { bool repeat = true; while (repeat) { string inputMonetaryValueInNumberic = string.Empty; string centPart = string.Empty; string dollarPart = string.Empty; Console.Write("\nEnter the monetary value : "); inputMonetaryValueInNumberic = Console.ReadLine(); inputMonetaryValueInNumberic = inputMonetaryValueInNumberic.TrimStart('0'); if (ValidateInput(inputMonetaryValueInNumberic)) { if (inputMonetaryValueInNumberic.Contains('.')) { centPart = ProcessCents(inputMonetaryValueInNumberic.Substring(inputMonetaryValueInNumberic.IndexOf(".") + 1)); dollarPart = ProcessDollar(inputMonetaryValueInNumberic.Substring(0, inputMonetaryValueInNumberic.IndexOf("."))); } else { dollarPart = ProcessDollar(inputMonetaryValueInNumberic); } centPart = string.IsNullOrWhiteSpace(centPart) ? string.Empty : " and " + centPart; Console.WriteLine(string.Format("\n\n{0}{1}", dollarPart, centPart)); } else { Console.WriteLine("Invalid Input.."); } Console.WriteLine("\n\nPress any key to continue or Escape of close : "); var loop = Console.ReadKey(); repeat = !loop.Key.ToString().Contains("Escape"); Console.Clear(); } } private static string ProcessCents(string cents) { string english = string.Empty; string dig3 = Process3Digit(cents); if (!string.IsNullOrWhiteSpace(dig3)) { dig3 = string.Format("{0} {1}", dig3, GetSections(0)); } english = dig3 + english; return english; } private static string ProcessDollar(string dollar) { string english = string.Empty; foreach (var item in Get3DigitList(dollar)) { string dig3 = Process3Digit(item.Value); if (!string.IsNullOrWhiteSpace(dig3)) { dig3 = string.Format("{0} {1}", dig3, GetSections(item.Key)); } english = dig3 + english; } return english; } private static string Process3Digit(string digit3) { string result = string.Empty; if (Convert.ToInt32(digit3) != 0) { int place = 0; Stack<string> monetaryValue = new Stack<string>(); for (int i = digit3.Length - 1; i >= 0; i--) { place += 1; string stringValue = string.Empty; switch (place) { case 1: stringValue = GetOnes(digit3[i].ToString()); break; case 2: int tens = Convert.ToInt32(digit3[i]); if (tens == 1) { if (monetaryValue.Count > 0) { monetaryValue.Pop(); } stringValue = GetTens((digit3[i].ToString() + digit3[i + 1].ToString())); } else { stringValue = GetTens(digit3[i].ToString()); } break; case 3: stringValue = GetOnes(digit3[i].ToString()); if (!string.IsNullOrWhiteSpace(stringValue)) { string postFixWith = " Hundred"; if (monetaryValue.Count > 0) { postFixWith = postFixWith + " And"; } stringValue += postFixWith; } break; } if (!string.IsNullOrWhiteSpace(stringValue)) monetaryValue.Push(stringValue); } while (monetaryValue.Count > 0) { result += " " + monetaryValue.Pop().ToString().Trim(); } } return result; } private static Dictionary<int, string> Get3DigitList(string monetaryValueInNumberic) { Dictionary<int, string> hundredsStack = new Dictionary<int, string>(); int counter = 0; while (monetaryValueInNumberic.Length >= 3) { string digit3 = monetaryValueInNumberic.Substring(monetaryValueInNumberic.Length - 3, 3); monetaryValueInNumberic = monetaryValueInNumberic.Substring(0, monetaryValueInNumberic.Length - 3); hundredsStack.Add(++counter, digit3); } if (monetaryValueInNumberic.Length != 0) hundredsStack.Add(++counter, monetaryValueInNumberic); return hundredsStack; } private static string GetTens(string tensPlaceValue) { string englishEquvalent = string.Empty; int value = Convert.ToInt32(tensPlaceValue); Dictionary<int, string> tens = new Dictionary<int, string>(); tens.Add(2, "Twenty"); tens.Add(3, "Thirty"); tens.Add(4, "Forty"); tens.Add(5, "Fifty"); tens.Add(6, "Sixty"); tens.Add(7, "Seventy"); tens.Add(8, "Eighty"); tens.Add(9, "Ninty"); tens.Add(10, "Ten"); tens.Add(11, "Eleven"); tens.Add(12, "Twelve"); tens.Add(13, "Thrteen"); tens.Add(14, "Fourteen"); tens.Add(15, "Fifteen"); tens.Add(16, "Sixteen"); tens.Add(17, "Seventeen"); tens.Add(18, "Eighteen"); tens.Add(19, "Ninteen"); if (tens.ContainsKey(value)) { englishEquvalent = tens[value]; } return englishEquvalent; } private static string GetOnes(string onesPlaceValue) { int value = Convert.ToInt32(onesPlaceValue); string englishEquvalent = string.Empty; Dictionary<int, string> ones = new Dictionary<int, string>(); ones.Add(1, " One"); ones.Add(2, " Two"); ones.Add(3, " Three"); ones.Add(4, " Four"); ones.Add(5, " Five"); ones.Add(6, " Six"); ones.Add(7, " Seven"); ones.Add(8, " Eight"); ones.Add(9, " Nine"); if (ones.ContainsKey(value)) { englishEquvalent = ones[value]; } return englishEquvalent; } private static string GetSections(int section) { string sectionName = string.Empty; switch (section) { case 0: sectionName = "Cents"; break; case 1: sectionName = "Dollars"; break; case 2: sectionName = "Thousand"; break; case 3: sectionName = "Million"; break; case 4: sectionName = "Billion"; break; case 5: sectionName = "Trillion"; break; case 6: sectionName = "Zillion"; break; } return sectionName; } private static bool ValidateInput(string input) { return Regex.IsMatch(input, "[0-9]{1,18}(\\.[0-9]{1,2})?")) } } } ``` #### @Rustem Mustafin 2016-12-01 15:07:46

Solution that takes up less code.

The most important part is only couple lines:

``````static Func<long, string> remainder = t => t > 0 ? " " + ToEN(t) : "";

public static string ToEN(this long val, double d = 20, long th = 20)
{
switch ((long)d)
{
case 20:   return val >= d ? ToEN(val, 1e2)             : en[val];
case 100:  return val >= d ? ToEN(val, 1e3, 100)        : en[val / 10 * 10] + remainder(val % 10);
default:   return val >= d ? ToEN(val, d * 1e3,(long)d) : ToEN(val / th) + " " + en[th] + remainder(val % th);
}
}
``````

Full code is available here https://dotnetfiddle.net/wjr4hF #### @HaBo 2016-11-23 14:38:05

Though this is kind of old question, I have implemented this functionality with more detailed approach

``````public static class NumberToWord
{
private static readonly Dictionary<long, string> MyDictionary = new Dictionary<long, string>();

static NumberToWord()
{
}

/// <summary>
/// To the verbal.
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static string ToVerbal(this int value)
{
}

/// <summary>
/// To the verbal.
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static string ToVerbal(this long value)
{
if (value == 0) return MyDictionary[value];

if (value < 0)
return \$" negative {ToVerbal(Math.Abs(value))}";

var builder = new StringBuilder();

for (var i = 1000000000000000; i >= 1000; i = i/1000)
value = ConstructWord(value, builder, i);

value = ConstructWord(value, builder, 100);

for (var i = 90; i >= 20; i = i - 10)
value = ConstructWordForTwoDigit(value, builder, i);

if (MyDictionary.ContainsKey(value))
builder.AppendFormat("{0}" + MyDictionary[value], builder.Length > 0
? " "
: string.Empty);

return builder.ToString();
}

private static long ConstructWord(long value, StringBuilder builder, long key)
{
if (value >= key)
{
var unit = (int) (value/key);
value -= unit*key;
builder.AppendFormat(" {0} {1} " + MyDictionary[key], builder.Length > 0
? ", "
: string.Empty, ToVerbal(unit));
}
return value;
}
private static long ConstructWordForTwoDigit(long value, StringBuilder builder, long key)
{
if (value >= key)
{
value -= key;
builder.AppendFormat(" {0} " + MyDictionary[key], builder.Length > 0
? " "
: string.Empty);
}
return value;
}
}
``````

FYI: i have user string interpolation which is only available in 4.6.1 #### @Aamol 2015-06-25 02:43:03

This class perfectly converts your float or double (till 2 precision). Just copy and paste in your IDE and see the result.

``````class ConversionClass
{
private static Dictionary<int, string> InitialNumbers = new Dictionary<int, string>();
private static Dictionary<int, string> MultipleOfTen = new Dictionary<int, string>();
private static Dictionary<int, string> MultipleOfHundered = new Dictionary<int, string>();

private static void InitializeStatic()
{

MultipleOfHundered.Add(6, "million");                      //          1 000 000
MultipleOfHundered.Add(7, "million");                      //        100 000 000
MultipleOfHundered.Add(8, "million");                      //      1 000 000 000
MultipleOfHundered.Add(9, "billion");                      //  1 000 000 000 000
}

public static void Main()
{
InitializeStatic();
Console.WriteLine("Enter number :");
double userValue ;
if (double.TryParse(userInput, out userValue))  // userValue = 193524019.50
{
int decimalPortion = (int)userValue;
//var fractionPortion = Math.Ceiling(((userValue < 1.0) ? userValue : (userValue % Math.Floor(userValue))) * 100);
int fractionPortion = (int)(userValue * 100) - ((int)userValue * 100);

int digit; int power;
StringBuilder numberInText = new StringBuilder();

while (decimalPortion > 0)
{
GetDigitAndPower(decimalPortion, out digit, out power);
numberInText.Append(ConvertToText(ref decimalPortion, ref digit, ref power));
if (decimalPortion > 0)
{
decimalPortion = GetReminder(decimalPortion, digit, power);
}
}
numberInText.Append(" point ");
while (fractionPortion > 0)
{
GetDigitAndPower(fractionPortion, out digit, out power);
numberInText.Append(ConvertToText(ref fractionPortion, ref digit, ref power));
if (fractionPortion > 0)
{
fractionPortion = GetReminder(fractionPortion, digit, power);
}
}

Console.WriteLine(numberInText.ToString());
}
}

private static int GetReminder(int orgValue, int digit, int power)
{
int returningValue = orgValue - (digit * (int)Math.Pow(10, power));
return returningValue;
}

private static void GetDigitAndPower(int originalValue, out int digit, out int power)
{
for (power = 0, digit = 0; power < 10; power++)
{
var divisionFactor = (int)Math.Pow(10, power);
int operationalValue = (originalValue / divisionFactor);
if (operationalValue <= 0)
{
power = power - 1;
digit = (int)(originalValue / Math.Pow(10, power));
break;
}
}
}

private static string ConvertToText(ref int orgValue, ref int digit, ref int power)
{
string numberToText = string.Empty;

if (power < 2)
{
if (InitialNumbers.ContainsKey(orgValue))
{
//This is for number 1 to 19
numberToText = InitialNumbers[orgValue];
orgValue = 0;
}
else if (MultipleOfTen.ContainsKey(digit))
{
//This is for multiple of 10 (20,30,..90)
numberToText = MultipleOfTen[digit];
}
}
else
{
if (power < 4)
{
numberToText = string.Format("{0} {1}", InitialNumbers[digit], MultipleOfHundered[power]);
}
else
{
StringBuilder sb = new StringBuilder();
int multiplicationFactor = power / 3;
int innerOrgValue = (int) (orgValue / Math.Pow(10, (multiplicationFactor * 3)));
digit = innerOrgValue;
var multiple = MultipleOfHundered[power];
power = power - ((int)Math.Ceiling(Math.Log10(innerOrgValue)) - 1);

int innerPower = 0;
int innerDigit = 0;
while (innerOrgValue > 0)
{
GetDigitAndPower(innerOrgValue, out innerDigit, out innerPower);
var text = ConvertToText(ref innerOrgValue, ref innerDigit, ref innerPower);
sb.Append(text);
sb.Append(" ");
if (innerOrgValue > 0)
{
innerOrgValue = GetReminder(innerOrgValue, innerDigit, innerPower);
}
}
sb.Append(multiple);
numberToText = sb.ToString();

}
}

return numberToText + " ";
}

}
`````` #### @Aamol 2015-06-25 02:58:06

@Hannele 's solution is also good but it fails for value : 10 000, 100 000 #### @i3arnon 2014-06-03 14:03:53

Currently the best, most robust, library for this is definitely Humanizer. It's open sourced and available as a nuget:

``````Console.WriteLine(4567788.ToWords()); // => four million five hundred and sixty-seven thousand seven hundred and eighty-eight
``````

It also has a wide range of tools solving the small problems every application has with `string`s, `enum`s, `DateTime`s, `TimeSpan`s and so forth, and supports many different languages.

``````Console.WriteLine(4567788.ToOrdinalWords().Underscore().Hyphenate().ApplyCase(LetterCasing.AllCaps)); // => FOUR-MILLION-FIVE-HUNDRED-AND-SIXTY-SEVEN-THOUSAND-SEVEN-HUNDRED-AND-EIGHTY-EIGHTH
`````` #### @Stéphane Gourichon 2016-03-13 18:31:37

Wow, that's multilingual: Afrikaans, Arabic, Bangla, BrazilianPortuguese, Dutch, English, Farsi, Finnish, French, German, Hebrew, Italian, NorwegianBokmal, Polish, Romanian, Russian, SerbianCyrl, Serbian, Slovenian, Spanish, Ukrainian. See at github.com/Humanizr/Humanizer/tree/dev/src/Humanizer/… #### @Ian Grainger 2016-04-14 08:55:13 #### @ryanwebjackson 2019-10-21 17:49:31

Any way to do the opposite? #### @Dennys Henry 2019-12-30 20:00:44

This is what everyone been looking for. Thank you #### @Elliot Wood 2014-08-08 05:38:13

In case anyone wants a JavaScript version

``````Number.prototype.numberToWords = function () {
var unitsMap = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"];
var tensMap = ["zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"];

var num = this.valueOf();
if (Math.round(num == 0)) {
return "zero";
}
if (num < 0) {
var positivenum = Math.abs(num);
return "minus " + Number(positivenum).numberToWords();
}
var words = "";
if (Math.floor(num / 1000000) > 0) {
words += Math.floor(num / 1000000).numberToWords() + " million ";
num = Math.floor(num % 1000000);
}
if (Math.floor(num / 1000) > 0) {
words += Math.floor(num / 1000).numberToWords() + " thousand ";
num = Math.floor(num % 1000);
}
if (Math.floor(num / 100) > 0) {
words += Math.floor(num / 100).numberToWords() + " hundred ";
num = Math.floor(num % 100);
}
if (Math.floor(num > 0)) {
if (words != "") {
words += "and ";
}
if (num < 20) {
words += unitsMap[num];
}
else {
words += tensMap[Math.floor(num / 10)];
if ((num % 10) > 0) {
words += "-" + unitsMap[Math.round(num % 10)];
}
}
}
return words.trim();
}
`````` #### @Joe Meyer 2012-07-18 17:11:55

http://www.exchangecore.com/blog/convert-number-words-c-sharp-console-application/ has some C# script that looks to handle very large numbers and very small decimals.

``````using System;
using System.Collections.Generic;
using System.Text;

namespace NumWords
{
class Program
{
// PROGRAM HANDLES NEGATIVE AND POSITIVE DOUBLES

static String NumWordsWrapper(double n)
{
string words = "";
double intPart;
double decPart = 0;
if (n == 0)
return "zero";
try {
string[] splitter = n.ToString().Split('.');
intPart = double.Parse(splitter);
decPart = double.Parse(splitter);
} catch {
intPart = n;
}

words = NumWords(intPart);

if (decPart > 0) {
if (words != "")
words += " and ";
int counter = decPart.ToString().Length;
switch (counter) {
case 1: words += NumWords(decPart) + " tenths"; break;
case 2: words += NumWords(decPart) + " hundredths"; break;
case 3: words += NumWords(decPart) + " thousandths"; break;
case 4: words += NumWords(decPart) + " ten-thousandths"; break;
case 5: words += NumWords(decPart) + " hundred-thousandths"; break;
case 6: words += NumWords(decPart) + " millionths"; break;
case 7: words += NumWords(decPart) + " ten-millionths"; break;
}
}
return words;
}

static String NumWords(double n) //converts double to words
{
string[] numbersArr = new string[] { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" };
string[] tensArr = new string[] { "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninty" };
string[] suffixesArr = new string[] { "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", "decillion", "undecillion", "duodecillion", "tredecillion", "Quattuordecillion", "Quindecillion", "Sexdecillion", "Septdecillion", "Octodecillion", "Novemdecillion", "Vigintillion" };
string words = "";

bool tens = false;

if (n < 0) {
words += "negative ";
n *= -1;
}

int power = (suffixesArr.Length + 1) * 3;

while (power > 3) {
double pow = Math.Pow(10, power);
if (n >= pow) {
if (n % pow > 0) {
words += NumWords(Math.Floor(n / pow)) + " " + suffixesArr[(power / 3) - 1] + ", ";
} else if (n % pow == 0) {
words += NumWords(Math.Floor(n / pow)) + " " + suffixesArr[(power / 3) - 1];
}
n %= pow;
}
power -= 3;
}
if (n >= 1000) {
if (n % 1000 > 0) words += NumWords(Math.Floor(n / 1000)) + " thousand, ";
else words += NumWords(Math.Floor(n / 1000)) + " thousand";
n %= 1000;
}
if (0 <= n && n <= 999) {
if ((int)n / 100 > 0) {
words += NumWords(Math.Floor(n / 100)) + " hundred";
n %= 100;
}
if ((int)n / 10 > 1) {
if (words != "")
words += " ";
words += tensArr[(int)n / 10 - 2];
tens = true;
n %= 10;
}

if (n < 20 && n > 0) {
if (words != "" && tens == false)
words += " ";
words += (tens ? "-" + numbersArr[(int)n - 1] : numbersArr[(int)n - 1]);
n -= Math.Floor(n);
}
}

return words;

}
static void Main(string[] args)
{
Console.Write("Enter a number to convert to words: ");

Console.WriteLine("{0}", NumWordsWrapper(n));
}
}
}
``````

EDIT: brought code over from blog post #### @Ruben Carreon 2011-10-19 23:40:55

if you use the code found in: converting numbers in to words C# and you need it for decimal numbers, here is how to do it:

``````public string DecimalToWords(decimal number)
{
if (number == 0)
return "zero";

if (number < 0)
return "minus " + DecimalToWords(Math.Abs(number));

string words = "";

int intPortion = (int)number;
decimal fraction = (number - intPortion)*100;
int decPortion = (int)fraction;

words = NumericToWords(intPortion);
if (decPortion > 0)
{
words += " and ";
words += NumericToWords(decPortion);
}
return words;
}
`````` #### @Patrick 2016-08-19 08:10:19

When I'm using decimal in the amount, I do not want "And" to occur twice, one with "Number to Words" one with "Decimal", it should only occur when there is no decimal, if there is a decimal, it should occur with decimal only. #### @Ahmar Husain 2013-01-17 12:13:40

``````namespace ConsoleApplication3
{

class Program
{

static void Main(string[] args)
{

ConvertMyword(int.Parse(s));

}

static void ConvertMyword(int number)
{
int flag = 0;
int lflag = 0;
string words = String.Empty;
string[] places = { "ones", "ten", "hundred", "thousand", "ten thousand", "lacs","tenlacs","crore","tencrore" };
string rawnumber = number.ToString();
char[] a = rawnumber.ToCharArray();
Array.Reverse(a);
for (int i = a.Length - 1; i >= 0; i--)
{
if (i % 2 == 0 && i > 2)
{
if (int.Parse(a[i].ToString()) > 1)
{
if (int.Parse(a[i - 1].ToString()) == 0)
{
words = words + getNumberStringty(int.Parse(a[i].ToString())) + " " + places[i - 1] + " ";
}
else
{
words = words + getNumberStringty(int.Parse(a[i].ToString())) + " ";
}
}
else if (int.Parse(a[i].ToString()) == 1)
{
if (int.Parse(a[i - 1].ToString())== 0)
{
words = words +"Ten" + " ";
}
else
{
words = words + getNumberStringteen(int.Parse(a[i - 1].ToString())) + " ";
}
flag = 1;
}
}
else
{
if (i == 1 || i == 0)
{
if (int.Parse(a[i].ToString()) > 1)
{
words = words + getNumberStringty(int.Parse(a[i].ToString())) + " " + getNumberString(int.Parse(a.ToString())) + " ";
break;
}
else if (int.Parse(a[i].ToString()) == 1)
{
if (int.Parse(a[i - 1].ToString()) == 0)
{
words = words + "Ten" + " ";
}
else
{
words = words + getNumberStringteen(int.Parse(a[i - 1].ToString())) + " ";
}

break;
}
else if (int.Parse(a[i - 1].ToString()) != 0)
{
words = words + getNumberString(int.Parse(a[i - 1].ToString())) + " ";
break;
}
else
{
break;
}
}
else
{
if (flag == 0)
{
for(int l=i;l>=0;l--)
{
if (int.Parse(a[l].ToString())!=0)
{
lflag = 1;
}
}
if (lflag == 1 && int.Parse(a[i].ToString())!=0)
{

words = words + getNumberString(int.Parse(a[i].ToString())) + " " + places[i] + " ";
lflag = 0;

}
else if(lflag == 0)
{
// words = words + getNumberString(int.Parse(a[i].ToString())) + " " + places[i] + " ";
lflag = 0;
break;
}

}
else
{
words = words + " " + places[i] + " ";
flag = 0;
}

}
}
}
Console.WriteLine(words);
}
static string getNumberString(int num)
{
string Word = String.Empty;
switch (num)
{
case 1:
Word = "one";
break;
case 2:
Word = "two";
break;

case 3:
Word = "three";
break;

case 4:
Word = "four";
break;

case 5:
Word = "five";
break;

case 6:
Word = "six";
break;
case 7:
Word = "seven";
break;

case 8:
Word = "eight";
break;

case 9:
Word = "nine";
break;

}
return Word;
}
static string getNumberStringty(int num)
{
string Word = String.Empty;
switch (num)
{

case 2:
Word = "twenty";
break;

case 3:
Word = "thirty";
break;

case 4:
Word = "fourty";
break;

case 5:
Word = "fifty";
break;

case 6:
Word = "sixty";
break;
case 7:
Word = "seventy";
break;

case 8:
Word = "eighty";
break;

case 9:
Word = "ninty";
break;

}
return Word;
}
static string getNumberStringteen(int num)
{
string Word = String.Empty;
switch (num)
{
case 1:
Word = "eleven";
break;
case 2:
Word = "tewlve";
break;

case 3:
Word = "thirteen";
break;

case 4:
Word = "fourteen";
break;

case 5:
Word = "fifteen";
break;

case 6:
Word = "sixteen";
break;
case 7:
Word = "seventeen";
break;

case 8:
Word = "eighteen";
break;

case 9:
Word = "ninteen";
break;

}
return Word;
}
}

}
`````` #### @Mitch 2012-09-24 06:16:44

``````Imports System.Text

Public Class NumberWriter

Public Shared Function Parse(ByVal Number As String) As String
If Not AreNumbers(Number) Then Return ""
Dim TempQueue As New Queue(Of String)
For Each ItemA As Char In Number.Replace(",", "").Reverse
TempQueue.Enqueue(ItemA)
Next
Dim Blocks As New List(Of String)
Dim BlockEmpty As New List(Of Boolean)
Do
Dim TempBlock As New StringBuilder(3)
TempBlock.Append(TempQueue.Dequeue)
If TempQueue.Count > 0 Then
TempBlock.Append(TempQueue.Dequeue)
If TempQueue.Count > 0 Then
TempBlock.Append(TempQueue.Dequeue)
End If
End If
If TempQueue.Count < 1 Then Exit Do
Loop
Dim ResultStack As New Stack(Of String)
For int1 As Integer = 0 To Blocks.Count - 1
ResultStack.Push(ReadBlock(Blocks(int1)) & If(Not int1 = 0, If(Not BlockEmpty(int1), " " & CapitalizeWord(GetPlaceValueSet(int1)) & If(BlockEmpty(int1 - 1), "", ", "), ""), ""))
Next
Dim Result1 As String = ""
Do Until ResultStack.Count < 1
Result1 &= ResultStack.Pop
Loop
Return RemoveGrammarErrors(Result1)
End Function

Private Shared Function RemoveGrammarErrors(ByVal Str As String) As String
Dim tstr As String = Str
tstr.Replace("  ", " ")
tstr.Replace(" , ", ", ")
Return tstr
End Function

Private Shared Function AreNumbers(ByVal Str1 As String) As Boolean
Dim Numbers() As String = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ","}
For Each ItemA As Char In Str1
Dim IsN As Boolean = False
For Each ItemB As String In Numbers
If ItemA = ItemB Then IsN = True
Next
If Not IsN Then
Return False
End If
Next
Return True
End Function

Private Shared Function ReadBlock(ByVal Block As String)
Select Case Block.Length
Case 1
Case 2
Case 3
Case Else
Throw New Exception
End Select
End Function

Private Shared Function ReadThreeDigits(ByVal Digits As String)
If Digits.Length > 3 Then Throw New ArgumentException("There are too many digits.")
Dim Result As String = ""
If Not Digits(0) = "0" Then
Result &= ReadSingleDigit(Digits(0)) & " Hundred "
End If
Return Result
End Function

Private Shared Function ReadTwoDigits(ByVal Digits As String)
If Digits.Length > 2 Then Throw New ArgumentException("There are too many digits.")
Select Case Digits(0)
Case "0"
Case "1"
Case Else
End Select
End Function

Private Shared Function ReadSingleDigit(ByVal Digit As String) As String
If Not Digit.Length = 1 Then Throw New ArgumentException("There must be only one digit and it must be more than zero.")
Select Case Digit
Case "0"
Return ""
Case "1"
Return "One"
Case "2"
Return "Two"
Case "3"
Return "Three"
Case "4"
Return "Four"
Case "5"
Return "Five"
Case "6"
Return "Six"
Case "7"
Return "Seven"
Case "8"
Return "Eight"
Case "9"
Return "Nine"
Case Else
Throw New Exception()
End Select
End Function

Private Shared Function ReadTeenNumber(ByVal Num As String) As String
Select Case Num
Case "11"
Return "Eleven"
Case "12"
Return "Twelve"
Case "13"
Return "Thirteen"
Case "14"
Return "Fourteen"
Case "15"
Return "Fifteen"
Case "16"
Return "Sixteen"
Case "17"
Return "Seventeen"
Case "18"
Return "Eighteen"
Case "19"
Return "Nineteen"
Case Else
Throw New Exception()
End Select
End Function

Private Shared Function ReadFirstInNumberPair(ByVal Num As String) As String
If Not (Num > 1 OrElse Num < 10) Then Throw New ArgumentException("Number must be more than 1 and less than 10")
Select Case Num
Case "2"
Return "Twenty"
Case "3"
Return "Thirty"
Case "4"
Return "Fourty"
Case "5"
Return "Fifty"
Case "6"
Return "Sixty"
Case "7"
Return "Seventy"
Case "8"
Return "Eighty"
Case "9"
Return "Ninety"
Case Else
Throw New Exception()
End Select
End Function

Private Shared Function CapitalizeWord(ByVal Word As String) As String
Return Word.Substring(0, 1).ToUpper & Word.Substring(1)
End Function

Private Shared Function GetPlaceValueSet(ByVal Num As Byte) As String
Select Case Num
Case 0
Return "" 'Hundreds
Case 1
Return "Thousand"
Case 2
Return "Million"
Case 3
Return "Billion"
Case 4
Return "Trillion"
Case 5
Case 6
Return "Quintillion"
Case 7
Return "Sextillion"
Case 8
Return "Septillion"
Case 9
Return "Octillion"
Case 10
Return "Nonillion"
Case 11
Return "octillion"
Case 12
Return "nonillion"
Case 13
Return "decillion"
Case 14
Return "undecillion"
Case 15
Return "dodecillion,"
Case 16
Return "tredecillion"
Case 17
Return "quattuordecillion"
Case 18
Return "quindecillion"
Case 19
Return "sexdecillion"
Case 20
Return "septendecillion"
Case 21
Return "octodecillion"
Case 22
Return "novemdecillion"
Case 23
Return "vigintillion"
Case 24
Return "unvigintillion"
Case 25
Return "dovigintillion"
Case 26
Return "trevigintillion"
Case 27
Return "quattuorvigintillion"
Case 28
Return "quinvigintillion"
Case 29
Return "sexvigintillion"
Case 30
Return "septenvigintillion"
Case 31
Return "octovigintillion"
Case 32
Return "novemvigintillion"
Case 33
Return "trigintillion"
Case 34
Return "untrigintillion"
Case 35
Return "dotrigintillion"
Case 36
Return "tretrigintillion"
Case 37
Return "quattuortrigintillion"
Case 38
Return "quintrigintillion"
Case 39
Return "sextrigintillion"
Case 40
Return "septentrigintillion"
Case 41
Return "octotrigintillion"
Case Else
Throw New Exception
End Select
End Function
End Class
``````

Sorry it's in VB.NET, but it works completely. It is one way. Number to Verbal. Handles numbers up to 123 characters long I believe.

### [SOLVED] In C#, how do I calculate someone's age based on a DateTime type birthday?

• 2008-07-31 23:40:59
• Jeff Atwood
• 617546 View
• 1882 Score
• Tags:   c# .net datetime

### [SOLVED] How do I create an Excel (.XLS and .XLSX) file in C# without installing Microsoft Office?

• 2008-09-29 22:30:28
• mistrmark
• 1105457 View
• 1903 Score
• Tags:   c# .net excel file-io

### [SOLVED] How to cast int to enum?

• 2008-08-27 03:58:21
• lomaxx
• 1408121 View
• 3227 Score
• Tags:   c# enums casting int

### [SOLVED] How can I generate random alphanumeric strings?

• 2009-08-27 23:07:24
• KingNestor
• 736419 View
• 988 Score
• Tags:   c# .net random

### [SOLVED] String representation of an Enum

• 2009-01-08 14:15:55
• user29964
• 764877 View
• 914 Score
• Tags:   c# enums