How do you convert numbers to words


Introduction

There are many solutions to converting numbers to words, the best one is a matter of choice, the bigger the number, the more you have to deal with, or do you!

If you think that the bigger the number, the more you have to do, then you would be wrong because the size of the number does not really matter, it is how you write your functions / methods that matter most.

Lets look at a number 678934.34, what are its properties?

There is a whole number and a decimal (fraction) part; the whole number part is made up of sets of 3 numbers, 678 and 934, if the number of characters in a particular set is 3, then that set of numbers can be written as hundreds, tens/teens or units if the number of characters in a set is only 2 then it will always be written as tens/teens and nits.

For example:

934 is written as "Nine hundred Thirty Four" or "Nine hundred Thirteen" if the number was 913, whether it is thousands, millions or trillions does not really matter, simply that any set of three (3) numbers is always written in either way.

So if any set of three numbers is written the same, how do we deal with thousands, millions, billions, the answer here is really simple, there is no rocket science to it.

The very first thing that needs to be done is declare the arrays of words

"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"
"ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
"hundred","thousand","million","billion","trillion","quadrillion","quintillion", ...

The first thing to do with whole numbers is to split the number into sets of numbers filling an array in reverse order;

678934 is clearly 2 sets of 3 numbers 678 and 934 so lets create an array with two elements

string[] numberSet = new string[2];

always do this in reverse order, the last set is always the first in, get it!

numberSet[0] = "934"
numberSet[1] =
"678"


At this point we know that each set of three numbers follows the same rule, that is hundred, tens/teens or units no matter where in the chain they exists.

Simple, isn't it!

What's next?

Easy as, element 0 is ALWAYS hundreds, element 1 is ALWAYS thousands, element 2 is ALWAYS millions, can you see where I am going!

No, hmmm, ok numberSet[0] translates to "Nine hundred Thirty Four" and numberSet[1] translates to "Six hundred Seventy Eight" right!

Remember we created the array of words, one of these arrays deals with the "BIG" names, so lets call the array bigNames,

By now you should know that the whole number in words is "Six hundred Seventy Eight Thousand, Nine hundred Thirty Four" (depending on which convention you use, US or UK)

So how do we get from knowing the words from the sets of three numbers to the whole number words, again very easily,

string the wholeNumberWords = ""

for(int i = numberSet.Length; i > 0; i--)
{
wholeNumberWords = numberSet[i] + " " + bigNames[i] + ", ";
}


Using this approach we have:

numberSet[0] translates to "Nine hundred Thirty Four" and
numberSet[1] translates to "Six hundred Seventy Eight"

numberSet[1] translates to "Six hundred Seventy Eight"

bigNames[1] translates to "thousand"

numberSet[0] translates to "Nine hundred Thirty Four" and
bigNames[0] translates to "hundred"

Put these together and we get, numberSet[1] + bigNames[1] + numberSet[0] + bigNames[0], in words "Six hundred Seventy Eight Thousand, Nine hundred Thirty Four"

Of course there are a lot of things you need to do to get to this point like, making the task a little easier by declaring an array of wordSets, this array will contain the
elements of the translated number sets (wordSets, [0] = "Nine hundred Thirty Four")

You also need to have functions / methods to translate each character of a numberSet eg;

string words(string number)
{
string n="", s="";
for(int i=0; i<3; i++)
{
n = numberSet[0].SubString(i, 1); //this does not take into account other factors, you will need to learn what the other conditions are...
s += unitsArray[Int.Parse(n)-1];

}

//the result is
//n = "9", s = unitsArray[9-1], s = unitsArray[8], s = "nine"
//n = "3", s = unitsArray[3-1], s = unitsArray[2], s = "three / thirty" (depends on other factors for testing conditions)
//n = "4", s = unitsArray[4-1], s = unitsArray[3], s = "four"
}


Ok we have looked at sets of numbers that can be treated as whole numbers of 3 but 012 is a set of three yet the word expected here is twelve not zero one two so what do you
do for these cases?

The first thing is to get rid of the 0 at position 1 because we do not say zero hundred and twenty three, we simply say twenty three or using 012 as an example, we say
twelve, so what are the conditions for whole numbers of two characters. (lets assume the number is 032)

The first condition is, is the number in the tens range (ten, twenty, thirty ...) or in the teens range (eleven, twelve, thirteen ...) if its in the tens range then we need
to look at the first character of the number and address the tens array @ element[n-1] n-1 being the first digit in the whole number, once we have the word from the tens range
wee need to look at the 2nd character of the whole number to determine which element in the units array we address, so if the character is a "2" we get the word at units[n-1]
in words, 032 becomes units[2] + " " + units[1] = " thirty two"


On the other hand, if the whole number is in the teens range (assume the number is 017) then we can completely ignor the last character in the number (7) and simply address
the teens array at element[(n-1)-10] in this case element[6] = "seventeen"

But if the whole number is "10" then it is clearly not in the teens and you cannot assume that the word should be translated to a unit word, we need to look at the last
character of the whole number, if it is a zero (0) then it can be ignored and the word for the whole number comes from the tens array at element[n-1], in this case element[0] = "ten"


Millions| thousands | hundreds | . |decimal|
-------------------------------------
| 6 | 7 | 8 | 9 | 3 | 4 | . | 3 | 4 |
-------------------------------------
| | |
| | -- Units "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"
| |
| ------ Tens / Teens "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" OR
| "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
|
|--------- Hundreds from Units + the word "hundred" (six + hundred )

-------------------------------------
Millions| thousands | hundreds | . |decimal|
-------------------------------------
| |
| -- "HUNDRED","thousand","million","billion","trillion","quadrillion","quintillion", ...
|
|------------ "hundred","THOUSAND","million","billion","trillion","quadrillion","quintillion", ...

When you have all the words representing the sets of numbers you can build the final string representing the number you want to translate to words.

Up to this point I have talked about whole numbers, what about the fraction or the decimal part of the number, this can be treated much the same way except that the conditions for testing will depend on the number being either a currency or a general number.

If the number is a currency then we need to look at the teens array or the units array only for example if the decimal part of a number is .56 then for currency we want to see fifty six but for a general number it is commonly worded as five six or point five six however, if the number is currency and the number past the decimal place is greater than 2 then the wording should be (assume .5672 cents) point five six seven two cents not fifty six seven two cents however you could do a little more condition testing and do something like fifty six point seven two cents.

When the number has been processed, it is time to assemble the words for the final output string, do this by traversing the words array in reverse order obtaining the big numbers name from the bigNumbers array based on the array position, bigNumbers[i-1]

string assembleWords()
{
int i;
tring a;
for(i = words.Length; i > 0; i--)
{
a += words[i-1] + " ";
if(i > 1)
a += bigNumbers[i-1] + ", ";
}
return(a);
}

The return value here is the words for the whole number so there is one thing left to do here, if it is currency then we attach the currency name for example "dollars" or "pounds", "drakma" etc.

Next step is to attaché the fraction/decimal words to complete the translation, in this case

Six hundred Seventy Eight Thousand, Nine hundred Thirty Four Dollars and Thirty Four Cents

Summary:

  1. Break apart the number you want to translate into it's elements

  2. Store the sets of numbers in an array of number sets making sure that the first nset of numbers in is the last set of numbers in the word

  3. Test each set of numbers from the numbers array and place them into a words array corresponding with the elements of the numbers array

  4. Build the word string using the words array.

Conclusion:

Converting a number to words is easy; all you need to do is understand the process to do it with, if you do it right, the same code to convert 3 numbers will also convert a number whose length exceeds the Centillion value (10^303) the googolplex is one such value;

1 Googol = 10 ^100
1 Googolplex = 1 ^Googol, this is one hell of a number and lets not even go there…

The attached application is written in C++

Numbers.gif

It will convert any number to the centillion value and does not require a DLL,

I have given you enough for you to write your own class but if you are unwilling to do that, I have written a DLL which can be called from your C# code, this is available to you for a small fee ($10US)