Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / All-Topics

Convert 3 Digit Number to Words (TIP)

0.00/5 (No votes)
28 Mar 2012LGPL33 min read 10.5K  
How to convert a 3 digit number to words

I was wandering through Codeproject as my daily routine and found one tip about Converting numbers to word. I actually got interested in it and began to read through and I was surprised at how easy the code was that the author had written. I also went through the comments section. People have expressed various views about it as well. I suggest you read through it.

So after completing the article, I wanted to improve the way in which it is implemented. Of course, I do not claim that it's the best solution. I have put in my effort for 2 hours and came up with the below code for the same 3 digit scenario.

So at first, I decided to have a lookup table kind of data structure for numbers to words. So I created a dictionary for the same as shown below:

C#
static Dictionary < int, NumbersPositionsInWords > numbersToWordsDictionary =
             new Dictionary < int, NumbersPositionsInWords >();

The value for the dictionary is a class which holds the positions words as shown below:

C#
class NumbersPositionsInWords
    {
        public string zeroPosition;//One, Two, Three
        public string tenthPosition;// Holds Twenty, Thirty, etc.
        public string elevenSeries;//Special words like 11 = Eleven, 12 = Twelve, etc.
    }

After I have this look up table frame being constructed which deals with all kinds of special words in the numbering system, next I need to fill the lookup table with the data. Below .cctor code does the same:

C#
static Program()
    {
       numbersToWordsDictionary.Add(1,
         new NumbersPositionsInWords()
         { zeroPosition = "One", tenthPosition = "Ten", elevenSeries = "Eleven" });

       numbersToWordsDictionary.Add(0,
         new NumbersPositionsInWords()
         { zeroPosition = "Zero", tenthPosition = null, elevenSeries = "Ten" });

       numbersToWordsDictionary.Add(2,
         new NumbersPositionsInWords()
         { zeroPosition = "Two", tenthPosition = "Twenty", elevenSeries = "Tweleve" });

       numbersToWordsDictionary.Add(3,
         new NumbersPositionsInWords()
         { zeroPosition = "Three", tenthPosition = "Thirty", elevenSeries = "Thirteen" });

       numbersToWordsDictionary.Add(4,
         new NumbersPositionsInWords()
         { zeroPosition = "Four", tenthPosition = "Fourty", elevenSeries = "Fourteen" });

       numbersToWordsDictionary.Add(5,
         new NumbersPositionsInWords()
         { zeroPosition = "Five", tenthPosition = "Fifty", elevenSeries = "Fifteen" });

       numbersToWordsDictionary.Add(6,
         new NumbersPositionsInWords()
         { zeroPosition = "Six", tenthPosition = "Sixty", elevenSeries = "Sixteen" });

       numbersToWordsDictionary.Add(7,
         new NumbersPositionsInWords()
         { zeroPosition = "Seven", tenthPosition = "Seventy", elevenSeries = "Seventeen" });

       numbersToWordsDictionary.Add(8,
         new NumbersPositionsInWords()
         { zeroPosition = "Eight", tenthPosition = "Eighty", elevenSeries = "Eighteen" });

       numbersToWordsDictionary.Add(9,
         new NumbersPositionsInWords()
         { zeroPosition = "Nine", tenthPosition = "Ninty", elevenSeries = "Ninteen" });

    }

Once I have full table data, next I have to take the input from the user and validate it as per requirement. The requirement I have assumed here is to have the input in integer format and with no less or greater than 3 digits.

Once I have validated the input, my next strategy is to split the 3 digit number into hundred, tenth and units positions. First, I consider the hundred position digit which is 0 index in input string. Once I get 0 index digit, I check if it’s not less than 1, i.e., 0, because if input number is 024, then it should not result in as Zero Hundred And Twenty Four rather it should be Twenty Four. Hence, I have to check for the 0 index digit (hundred position digit) and then construct the output string as per the lookup table. The below code does the same logic:

C#
int hundredthPostionDigit = GetDigitFromPosition(inputString, 0);
StringBuilder resultString = new StringBuilder();

if (hundredthPostionDigit > 0)
  resultString.AppendFormat("{0}{1} {2}",
  numbersToWordsDictionary[hundredthPostionDigit].zeroPosition,
  string.Empty, hundredString);

Once the basic string (left to write parsing) is constructed, the next thing for me is to consider the tenth and unit position together. This is because, at different conditions (11, 03, etc.), I need to parse and convert to equivalent words. Hence, the below code does the same:

C#
if (tenthPositionDigit > 1)//For 45, 98, it should be Forty Five, etc.
 numberToWordText.AppendFormat("{0} {1}",
 numbersToWordsDictionary[tenthPositionDigit].tenthPosition,
 unitsPositionDigit != 0 ? numbersToWordsDictionary[unitsPositionDigit].zeroPosition :
 string.Empty);

if (tenthPositionDigit < 1)//For 02, 06, 00 it should be just pick unit digit or none.
 numberToWordText.AppendFormat("{0}", unitsPositionDigit > 0 ?
 numbersToWordsDictionary[unitsPositionDigit].zeroPosition : string.Empty);

//For 11, 13, 14 it should be special words like eleven, twelve, etc.
if (tenthPositionDigit == 1)
 numberToWordText.AppendFormat("{0}", unitsPositionDigit == tenthPositionDigit ?
 numbersToWordsDictionary[tenthPositionDigit].elevenSeries :
 numbersToWordsDictionary[unitsPositionDigit].elevenSeries);

The appended text could be either empty (in case of 100, 200, 500, etc.) or with valid content like Twenty Five, Ninty One, etc. This text is then consumed back to append to the actual resulting string for display and the below code does the same:

C#
if (resultString.Length > 0 && numberToWordText.Length > 0)
  resultString.AppendFormat(" {0} {1}", "And", numberToWordText);
else resultString.Append(numberToWordText);

You can get the full formatted, compilable source code from here: http://ideone.com/LEYQ1.

That’s all, my friend. I wanted to keep it as simple as possible and I did it/wanted to spend very minimal time writing this logic. Thanks goes to the original author from CodeProject (article linked above).

Disclaimer: I have not given enough concentration/efforts to make the code better. I do agree that there is a lot to improve in terms of design? Refactoring? Maintainability? Extensibility? etc. I shall aim to improve the code and consult my smart colleagues/friends for suggestions to improve this code, then update the same in my blog post.
However, please feel free to give your comments/ideas here for my learning.

Thanks and happy coding,
Zen :)


Filed under: C#, CodeProject, Dotnet
Tagged: .NET, 2012, Bing, Blog, Blogger, C#, codeproject, Data structure, Dotnet, geek, google, Programming, Source code, tips, wordpress

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)