Is there a built in method in .NET to convert a number to the string representation of the number? For example, 1 becomes one, 2 becomes two, etc.
11 Answers
I've always been a fan of the recursive method
public static string NumberToText( int n)
{
if ( n < 0 )
return "Minus " + NumberToText(-n);
else if ( n == 0 )
return "";
else if ( n <= 19 )
return new string[] {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen",
"Seventeen", "Eighteen", "Nineteen"}[n-1] + " ";
else if ( n <= 99 )
return new string[] {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy",
"Eighty", "Ninety"}[n / 10 - 2] + " " + NumberToText(n % 10);
else if ( n <= 199 )
return "One Hundred " + NumberToText(n % 100);
else if ( n <= 999 )
return NumberToText(n / 100) + "Hundreds " + NumberToText(n % 100);
else if ( n <= 1999 )
return "One Thousand " + NumberToText(n % 1000);
else if ( n <= 999999 )
return NumberToText(n / 1000) + "Thousands " + NumberToText(n % 1000);
else if ( n <= 1999999 )
return "One Million " + NumberToText(n % 1000000);
else if ( n <= 999999999)
return NumberToText(n / 1000000) + "Millions " + NumberToText(n % 1000000);
else if ( n <= 1999999999 )
return "One Billion " + NumberToText(n % 1000000000);
else
return NumberToText(n / 1000000000) + "Billions " + NumberToText(n % 1000000000);
}

- 15,461
- 8
- 52
- 69
-
Nicely done, you should modify it at least to receive longs though. +1 – BenAlabaster Apr 27 '09 at 19:04
-
3I liked your code as it was easier to follow than balabaster's. I modified it a bit to account for a single "0" parameter (returns "Zero"), to accept a long rather than an int, and to return Billion instead of Billions, Million instead of Millions, etc. Good code! – Mike Cole Apr 27 '09 at 20:49
-
@Ryan : i understood your solution but can you explain me the second square bracket operator you used when returning a new string ( if n <= 19 ), as i have not used that style before and didn't understand it. Thanks ! – skywalker2909 Jun 13 '14 at 19:41
-
Ah, there may not be a class to do this, but there was a code golf question which I provided a C# example for:
However, it's not the easiest to read and it only goes up to decimal.MaxValue, so I've written a new version that will go as high as you need to.
I couldn't find any information regarding values higher than vigintillions, but if you append the values to the thou[] array, you can continue going up as far as you like. It still doesn't support fractions, but I'm thinking about adding that at some point.
static string NumericStringToWords(string NumericValue)
{
if ("0" == NumericValue) return "zero";
string[] units = { "one", "two", "three", "four", "five",
"six", "seven", "eight", "nine" };
string[] teens = { "eleven", "twelve", "thirteen", "four", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen" };
string[] tens = { "ten", "twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety" };
string[] thou = { "thousand", "million", "billion", "trillion",
"quadrillion", "quintillion", "sextillion",
"septillion", "octillion", "nonillion", "decillion",
"udecillion", "duodecillion", "tredecillion",
"quattuordecillion", "quindecillion", "sexdecillion",
"septendecillion", "octodecillion", "novemdecillion",
"vigintillion" };
string sign = String.Empty;
if ("-" == NumericValue.Substring(0, 1))
{
sign = "minus ";
NumericValue = NumericValue.Substring(1);
}
int maxLen = thou.Length * 3;
int actLen = NumericValue.Length;
if(actLen > maxLen)
throw new InvalidCastException(String.Format("{0} digit number specified exceeds the maximum length of {1} digits. To evaluate this number, you must first expand the thou[] array.", actLen, maxLen));
//Make sure that the value passed in is indeed numeric... we parse the entire string
//rather than just cast to a numeric type to allow us to handle large number types passed
//in as a string. Otherwise, we're limited to the standard data type sizes.
int n; //We don't care about n, but int.TryParse requires it
if (!NumericValue.All(c => int.TryParse(c.ToString(), out n)))
throw new InvalidCastException();
string fraction = String.Empty;
if (NumericValue.Contains("."))
{
string[] split = NumericValue.Split('.');
NumericValue = split[0];
fraction = split[1];
}
StringBuilder word = new StringBuilder();
ulong loopCount = 0;
while (0 < NumericValue.Length)
{
int startPos = Math.Max(0, NumericValue.Length - 3);
string crntBlock = NumericValue.Substring(startPos);
if (0 < crntBlock.Length)
{
//Grab the hundreds tens & units for the current block
int h = crntBlock.Length > 2 ? int.Parse(crntBlock[crntBlock.Length - 3].ToString()) : 0;
int t = crntBlock.Length > 1 ? int.Parse(crntBlock[crntBlock.Length - 2].ToString()) : 0;
int u = crntBlock.Length > 0 ? int.Parse(crntBlock[crntBlock.Length - 1].ToString()) : 0;
StringBuilder thisBlock = new StringBuilder();
if (0 < u)
thisBlock.Append(1 == t? teens[u - 1] : units[u - 1]);
if (1 != t)
{
if (1 < t && 0 < u) thisBlock.Insert(0, "-");
if (0 < t) thisBlock.Insert(0, tens[t - 1]);
}
if (0 < h)
{
if (t > 0 | u > 0) thisBlock.Insert(0, " and ");
thisBlock.Insert(0, String.Format("{0} hundred", units[h - 1]));
}
//Check to see if we've got any data left and add
//appropriate word separator ("and" or ",")
bool MoreLeft = 3 < NumericValue.Length;
if (MoreLeft && (0 == h) && (0 == loopCount))
thisBlock.Insert(0, " and ");
else if (MoreLeft)
thisBlock.Insert(0, String.Format(" {0}, ", thou[loopCount]));
word.Insert(0, thisBlock);
}
//Remove the block we just evaluated from the
//input string for the next loop
NumericValue = NumericValue.Substring(0, startPos);
loopCount++;
}
return word.Insert(0, sign).ToString();
}
I tested it using Decimal.MaxValue appended to itself to generate a large number of:
seven octodecillion, nine hundred and twenty-two septendecillion, eight hundred and sixteen sexdecillion, two hundred and fifty-one quindecillion, four hundred and twenty-six quattuordecillion, four hundred and thirty-three tredecillion, seven hundred and fifty-nine duodecillion, three hundred and fifty-four udecillion, three hundred and ninety-five decillion, thirty-three nonillion, five hundred and seventy-nine octillion, two hundred and twenty-eight septillion, one hundred and sixty-two sextillion, five hundred and four quintillion, two hundred and sixty-four quadrillion, three hundred and thirty-seven trillion, five hundred and ninety-three billion, five hundred and forty-three million, nine hundred and fifty- thousand, three hundred and thirty-five

- 1
- 1

- 39,070
- 21
- 110
- 151
-
@BobTheBuilder: LOL, maybe, but I'm not sure how I'd write most of the fractions. Do you write them as hundredths, thousandths, or just "point zero five three nine..." or do you write them as actual fractions like three fifths etc.? – BenAlabaster Apr 27 '09 at 18:42
-
How about .1 = "one tenth", .14 = "fourteen hundredths", .141 = "one hundred forty one thousandths" and so on? =P – Neil Williams Apr 27 '09 at 19:20
-
1@Neil Williams: Actually, I'm not sure that would work so well on larger numbers or on long fractions as it could make it more confusing to read than using point zero seven nine... etc. – BenAlabaster Apr 28 '09 at 17:23
public string IntToString(int number)//nobody really uses negative numbers
{
if(number == 0)
return "zero";
else
if(number == 1)
return "one";
.......
else
if(number == 2147483647)
return "two billion one hundred forty seven million four hundred eighty three thousand six hundred forty seven";
}

- 30,738
- 21
- 105
- 131

- 7,162
- 11
- 46
- 70
-
5
-
4No, but it should be. What was I thinking with all those else if's. I should have used a switch. – Kevin Apr 30 '09 at 17:57
-
2I'm tempted to downvote this, but it's so bad that it actually reversed my decision.. +1 for humor sense. – nawfal Dec 29 '13 at 23:59
-
Late to the party, But the OP didn't ask any recursion or general solution, this indeed solves the OP's question. +1 for rofl :) – Patrick Apr 03 '15 at 11:05
-
Here is the modified code I used:
//Wrapper class for NumberToText(int n) to account for single zero parameter.
public static string ConvertToStringRepresentation(long number)
{
string result = null;
if (number == 0)
{
result = "Zero";
}
else
{
result = NumberToText(number);
}
return result;
}
//Found at http://www.dotnet2themax.com/blogs/fbalena/PermaLink,guid,cdceca73-08cd-4c15-aef7-0f9c8096e20a.aspx.
//Modifications from original source:
// Changed parameter type from int to long.
// Changed labels to be singulars instead of plurals (Billions to Billion, Millions to Million, etc.).
private static string NumberToText(long n)
{
if (n < 0)
return "Minus " + NumberToText(-n);
else if (n == 0)
return "";
else if (n <= 19)
return new string[] {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen",
"Seventeen", "Eighteen", "Nineteen"}[n - 1] + " ";
else if (n <= 99)
return new string[] {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy",
"Eighty", "Ninety"}[n / 10 - 2] + " " + NumberToText(n % 10);
else if (n <= 199)
return "One Hundred " + NumberToText(n % 100);
else if (n <= 999)
return NumberToText(n / 100) + "Hundred " + NumberToText(n % 100);
else if (n <= 1999)
return "One Thousand " + NumberToText(n % 1000);
else if (n <= 999999)
return NumberToText(n / 1000) + "Thousand " + NumberToText(n % 1000);
else if (n <= 1999999)
return "One Million " + NumberToText(n % 1000000);
else if (n <= 999999999)
return NumberToText(n / 1000000) + "Million " + NumberToText(n % 1000000);
else if (n <= 1999999999)
return "One Billion " + NumberToText(n % 1000000000);
else
return NumberToText(n / 1000000000) + "Billion " + NumberToText(n % 1000000000);
}
This thread was a great help. I like Ryan Emerle's solution the best for its clarity. Here's my version which I think makes the structure clear as day:
public static class Number
{
static string[] first =
{
"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine",
"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen",
"Seventeen", "Eighteen", "Nineteen"
};
static string[] tens =
{
"Twenty", "Thirty", "Fourty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety",
};
/// <summary>
/// Converts the given number to an english sentence.
/// </summary>
/// <param name="n">The number to convert.</param>
/// <returns>The string representation of the number.</returns>
public static string ToSentence(int n)
{
return n == 0 ? first[n] : Step(n);
}
// traverse the number recursively
public static string Step(int n)
{
return n < 0 ? "Minus " + Step(-n):
n == 0 ? "":
n <= 19 ? first[n]:
n <= 99 ? tens[n / 10 - 2] + " " + Step(n % 10):
n <= 199 ? "One Hundred " + Step(n % 100):
n <= 999 ? Step(n / 100) + "Hundred " + Step(n % 100):
n <= 1999 ? "One Thousand " + Step(n % 1000):
n <= 999999 ? Step(n / 1000) + "Thousand " + Step(n % 1000):
n <= 1999999 ? "One Million " + Step(n % 1000000):
n <= 999999999 ? Step(n / 1000000) + "Million " + Step(n % 1000000):
n <= 1999999999 ? "One Billion " + Step(n % 1000000000):
Step(n / 1000000000) + "Billion " + Step(n % 1000000000);
}
}

- 2,514
- 1
- 27
- 32
-
1+1 for clarity and making the "constants" a static value, as opposed to the other solutions declaring them inline. – drzaus Feb 15 '13 at 16:52
Based on Ryan Emerle's solution, this adds dashes at the correct locations, does not include trailing spaces, does not pluralize numbers, and properly handles an input of zero (0):
public static string ToText(long n) {
return _toText(n, true);
}
private static string _toText(long n, bool isFirst = false) {
string result;
if(isFirst && n == 0) {
result = "Zero";
} else if(n < 0) {
result = "Negative " + _toText(-n);
} else if(n == 0) {
result = "";
} else if(n <= 9) {
result = new[] { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" }[n - 1] + " ";
} else if(n <= 19) {
result = new[] { "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" }[n - 10] + (isFirst ? null : " ");
} else if(n <= 99) {
result = new[] { "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }[n / 10 - 2] + (n % 10 > 0 ? "-" + _toText(n % 10) : null);
} else if(n <= 999) {
result = _toText(n / 100) + "Hundred " + _toText(n % 100);
} else if(n <= 999999) {
result = _toText(n / 1000) + "Thousand " + _toText(n % 1000);
} else if(n <= 999999999) {
result = _toText(n / 1000000) + "Million " + _toText(n % 1000000);
} else {
result = _toText(n / 1000000000) + "Billion " + _toText(n % 1000000000);
}
if(isFirst) {
result = result.Trim();
}
return result;
}

- 139
- 1
- 2
Here's my refined version of the first answer. I hope it's useful.
/// <summary>
/// Converts an <see cref="int"/> to its textual representation
/// </summary>
/// <param name="num">
/// The number to convert to text
/// </param>
/// <returns>
/// A textual representation of the given number
/// </returns>
public static string ToText(this int num)
{
StringBuilder result;
if (num < 0)
{
return string.Format("Minus {0}", ToText(-num));
}
if (num == 0)
{
return "Zero";
}
if (num <= 19)
{
var oneToNineteen = new[]
{
"One",
"Two",
"Three",
"Four",
"Five",
"Six",
"Seven",
"Eight",
"Nine",
"Ten",
"Eleven",
"Twelve",
"Thirteen",
"Fourteen",
"Fifteen",
"Sixteen",
"Seventeen",
"Eighteen",
"Nineteen"
};
return oneToNineteen[num - 1];
}
if (num <= 99)
{
result = new StringBuilder();
var multiplesOfTen = new[]
{
"Twenty",
"Thirty",
"Forty",
"Fifty",
"Sixty",
"Seventy",
"Eighty",
"Ninety"
};
result.Append(multiplesOfTen[(num / 10) - 2]);
if (num % 10 != 0)
{
result.Append(" ");
result.Append(ToText(num % 10));
}
return result.ToString();
}
if (num == 100)
{
return "One Hundred";
}
if (num <= 199)
{
return string.Format("One Hundred and {0}", ToText(num % 100));
}
if (num <= 999)
{
result = new StringBuilder((num / 100).ToText());
result.Append(" Hundred");
if (num % 100 != 0)
{
result.Append(" and ");
result.Append((num % 100).ToText());
}
return result.ToString();
}
if (num <= 999999)
{
result = new StringBuilder((num / 1000).ToText());
result.Append(" Thousand");
if (num % 1000 != 0)
{
switch ((num % 1000) < 100)
{
case true:
result.Append(" and ");
break;
case false:
result.Append(", ");
break;
}
result.Append((num % 1000).ToText());
}
return result.ToString();
}
if (num <= 999999999)
{
result = new StringBuilder((num / 1000000).ToText());
result.Append(" Million");
if (num % 1000000 != 0)
{
switch ((num % 1000000) < 100)
{
case true:
result.Append(" and ");
break;
case false:
result.Append(", ");
break;
}
result.Append((num % 1000000).ToText());
}
return result.ToString();
}
result = new StringBuilder((num / 1000000000).ToText());
result.Append(" Billion");
if (num % 1000000000 != 0)
{
switch ((num % 1000000000) < 100)
{
case true:
result.Append(" and ");
break;
case false:
result.Append(", ");
break;
}
result.Append((num % 1000000000).ToText());
}
return result.ToString();
}

- 113,022
- 33
- 324
- 344

- 752
- 2
- 11
- 16
There's no built in solution in .net
, but there are good libraries around. The best currently is definitely Humanizr:
Console.WriteLine(794663.ToWords()); // => seven hundred and ninety-four thousand six hundred and sixty-three
It also supports ordinal, and roman representations:
Console.WriteLine(794663.ToOrdinalWords()); // => seven hundred and ninety-four thousand six hundred and sixty third
Console.WriteLine(794.ToRoman()); // => DCCXCIV
Humanizr
also has a wide range of tools regarding string
, DateTime
, TimeSpan
and so forth.
Console.WriteLine(794.Seconds().Humanize().Underscore().Hyphenate()); // => 13-minutes

- 113,022
- 33
- 324
- 344
A conversion from integer to long form English... I could write that ;-) is a pretty good article on the topic:
using System;
public class NumberToEnglish {
private static string[] onesMapping =
new string[] {
"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine",
"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"
};
private static string[] tensMapping =
new string[] {
"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"
};
private static string[] groupMapping =
new string[] {
"Hundred", "Thousand", "Million", "Billion", "Trillion"
};
private static void Main(string[] args) {
Console.WriteLine(EnglishFromNumber(long.Parse(args[0])));
}
private static string EnglishFromNumber(int number) {
return EnglishFromNumber((long) number);
}
private static string EnglishFromNumber(long number) {
if ( number == 0 ) {
return onesMapping[number];
}
string sign = "Positive";
if ( number < 0 ) {
sign = "Negative";
number = Math.Abs(number);
}
string retVal = null;
int group = 0;
while(number > 0) {
int numberToProcess = (int) (number % 1000);
number = number / 1000;
string groupDescription = ProcessGroup(numberToProcess);
if ( groupDescription != null ) {
if ( group > 0 ) {
retVal = groupMapping[group] + " " + retVal;
}
retVal = groupDescription + " " + retVal;
}
group++;
}
return sign + " " + retVal;
}
private static string ProcessGroup(int number) {
int tens = number % 100;
int hundreds = number / 100;
string retVal = null;
if ( hundreds > 0 ) {
retVal = onesMapping[hundreds] + " " + groupMapping[0];
}
if ( tens > 0 ) {
if ( tens < 20 ) {
retVal += ((retVal != null) ? " " : "") + onesMapping[tens];
} else {
int ones = tens % 10;
tens = (tens / 10) - 2; // 20's offset
retVal += ((retVal != null) ? " " : "") + tensMapping[tens];
if ( ones > 0 ) {
retVal += ((retVal != null) ? " " : "") + onesMapping[ones];
}
}
}
return retVal;
}
}

- 30,738
- 21
- 105
- 131

- 28,337
- 7
- 52
- 74
-
1@balabaster: Nor as inclusive as your code golf version, but it *is* easier to read – BobTheBuilder Apr 27 '09 at 18:36
-
@BobTheBuilder: Yeah, but like I said, that's not the purpose of code golf :P – BenAlabaster Apr 27 '09 at 18:39
Another naasking, version in VB.NET if any one is interested! Had to use the floor function to round properly..
Public Function NumberToText(n As Integer) As String
Dim a As String() = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}
Dim tens As String() = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy",
"Eighty", "Ninety"}
If (n < 0) Then
Return "Minus " + NumberToText(-n)
ElseIf (n = 0) Then
Return ""
ElseIf (n <= 19) Then
Return a(n - 1) + " "
ElseIf (n <= 99) Then
Return tens(Math.Floor(n / 10) - 2) + " " + NumberToText(n Mod 10)
ElseIf (n <= 199) Then
Return "One Hundred " + NumberToText(n Mod 100)
ElseIf (n <= 999) Then
Return NumberToText(Math.Floor(n / 100)) + "Hundreds " + NumberToText(n Mod 100)
ElseIf (n <= 1999) Then
Return "One Thousand " + NumberToText(n Mod 1000)
ElseIf (n <= 999999) Then
Return NumberToText(Math.Floor(n / 1000)) + "Thousands " + NumberToText(n Mod 1000)
ElseIf (n <= 1999999) Then
Return "One Million " + NumberToText(n Mod 1000000)
ElseIf (n <= 999999999) Then
Return NumberToText(Math.Floor(n / 1000000)) + "Millions " + NumberToText(n Mod 1000000)
ElseIf (n <= 1999999999) Then
Return "One Billion " + NumberToText(n Mod 1000000000)
Else
Return NumberToText(Math.Floor(n / 1000000000)) + "Billions " + NumberToText(n Mod 1000000000)
End If
End Function

- 402
- 1
- 6
- 11
Here is a more complete/improved solution based on a couple ideas also posted here. Includes grammar/hyphen fixes, and optional capitalization, long support, support for zero, and yet still very succinct (VB.Net):
Function NumberToCapitalizedWords(ByVal n As Long) As String
Return New System.Globalization.CultureInfo("en-US", False).TextInfo.ToTitleCase(NumberToWords(n))
End Function
Function NumberToWords(ByVal n As Long) As String
Return LTrim(NumberToWords(n, False, False))
End Function
Function NumberToWords(ByVal n As Long, ByVal recursed As Boolean, ByVal iesLast As Boolean) As String
If (n < 0) Then
Return "negative" + NumberToWords(-n, False, False)
ElseIf (n = 0) Then
If recursed Then
Return ""
End If
Return "zero"
ElseIf (n < 20) Then
Return If(iesLast, "-", " ") + New String() {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}(n - 1)
ElseIf (n < 100) Then
Return " " + New String() {"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"}(n \ 10 - 2) + NumberToWords(n Mod 10, True, True)
ElseIf (n < 1000) Then
Return NumberToWords(n \ 100, True, False) + " hundred" + NumberToWords(n Mod 100, True, False)
Else
Dim log1000 As Integer = Math.Floor(Math.Log(n, 1000))
Return NumberToWords(n \ PowerNoFloat(1000, log1000), True, False) + " " + New String() {"thousand", "million", "billion", "trillion", "quadrillion", "quintillion"}(log1000 - 1) + NumberToWords(n Mod PowerNoFloat(1000, log1000), True, False)
End If
End Function
Function PowerNoFloat(ByRef base As Long, ByRef power As Integer) As Long
If power < 0 Then
Return 0
End If
Dim result As Long = 1
For i As Integer = 1 To power
result *= base
Next
Return result
End Function

- 1,698
- 17
- 27
-
I added the extra power function because the built in language function returns a double which can cause discrepancies. – Nick Kuznia May 08 '15 at 18:52