tags:

views:

1139

answers:

9

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.

A: 

No, there is no such built-in class or method.

Mihai Limbășan
+1  A: 

This is a pretty good article on the topic:

http://weblogs.asp.net/justin_rogers/archive/2004/06/09/151675.aspx

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;
    }
}
BobbyShaftoe
Obviously not a code golf contender :P
BenAlabaster
@balabaster: Nor as inclusive as your code golf version, but it *is* easier to read
BobTheBuilder
@BobTheBuilder: Yeah, but like I said, that's not the purpose of code golf :P
BenAlabaster
A: 

No, theres no built-in mechanism to do this.

You'd need to hand craft something for your spoken/written language (in your case english) ala

http://www.hotblue.com/article0001.aspx

Eoin Campbell
+7  A: 
BenAlabaster
+1 for going up so far... you should add decimal places too...
BobTheBuilder
@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
How about .1 = "one tenth", .14 = "fourteen hundredths", .141 = "one hundred forty one thousandths" and so on? =P
Neil Williams
It's under consideration :)
BenAlabaster
@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
+7  A: 

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);
}

Source

Ryan Emerle
Nicely done, you should modify it at least to receive longs though. +1
BenAlabaster
I 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 C.
See my post for modified code.
Mike C.
A: 

Don't forget to check the CurrentCulture to see if in your contry a billion has 9 or 12 zeros...

Jonathan
+1  A: 

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);
    }
Mike C.
A: 

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";

}
Kevin
Didn't I see this on Daily WTF?
Mike C.
No, but it should be. What was I thinking with all those else if's. I should have used a switch.
Kevin
A: 

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);
    }
}
naasking