On many accounting software, sometimes you need to convert the current number to words. This can be done by make a function which will return a string of number given by input parameter. The function itself actually is very easy to make, if you want basic converting of course. The interesting part is that each developer has unique way to make this algorithm. And because it's wide solution that can be produced, this problem often used by programming courses to make their students understand about algorithm.
To make a good number to word converter, first we must understand how to pronounce those words. In this part, we will make an English converter. Part II will have an Indonesian converter.
Basic Understanding
First rule of converting number is to know the prefix. In English, the common prefixes are hundred, thousand, million, billion, and trillion. I called these by "level". So, we need 5 type of level, right ? Well, not quite right. Actually, we only need 4 type of level. Hundred can be repeated in every level. Ex: 1100 (One thousand one hundred), and 1000100 (One Million One hundred). Now, let's make a function for this level.
Code 1 |
Private Shared Function EnglishLevel(ByVal level As String) As String Dim retval As String = ""
Select Case level Case 0 retval = "thousand " Case 1 retval = "million " Case 2 retval = "billion " Case 3 retval = "trillion " End Select
Return retval End Function
|
Now me will create a default number to word function. This function will return a string represent the number given in it's parameter. You can see the snippet in code 2.
Code 2 |
Private Shared Function EnglishNumber(ByVal num As String) As String Dim retval As String = ""
Select Case num Case 1 retval = "one" Case 2 retval = "two" Case 3 retval = "three" Case 4 retval = "four" Case 5 retval = "five" Case 6 retval = "six" Case 7 retval = "seven" Case 8 retval = "eight" Case 9 retval = "nine" End Select
Return retval End Function
|
Pattern Understanding
Before we make the main function, we should think about the pattern algorithm first and design the function. In this section, I'll explain about how the algorithm works.
The first pattern that you should know, is that within the prefix, the word is repeat them self. Lets see this example: 123,123 (One hundred twenty three thousand one hundred twenty three). Even for 123,123,123; the pattern will be same. All you have to add is only the prefix. By analyze this pattern, we only need a function to define the prefix (which I already add in above), and a function to define the number, and repeat itself. For my solution, I'll use a recursion and playing with reference passing and default math functions.
The second and third patterns are "ty" and "teen" prefix. Some numbers don't change their pronunciations ("sixty"/"sixteen", "seventy"/"seventeen"), but some does change ("fifty"/"fifteen" not "fivety"/"fiveteen"). Luckily, some of those numbers won't have a specific word between "ty" and "teen". Three exceptions are for 10, 11, and 12. Therefore, we should modify our EnglishNumber function from Code 2 in to this.
Code 2 - Revised. |
Private Shared Function EnglishNumber(ByVal num As String, _ ByVal special As Boolean) As String Dim retval As String = ""
Select Case num Case 1 retval = "one" Case 2 If special Then retval = "twen" Else retval = "two" End If Case 3 If special Then retval = "thir" Else retval = "three" End If Case 4 retval = "four" Case 5 If special Then retval = "fif" Else retval = "five" End If Case 6 retval = "six" Case 7 retval = "seven" Case 8 If special Then retval = "eigh" Else retval = "eight" End If Case 9 retval = "nine" End Select
Return retval End Function
|
Make Main Function
Finally, all we need is the main function that will be called. Remember that we only need to parse 3 number each prefix, since it will repeat after a prefix was given. For this method, I'll use a recursive approach.
First, we separate hundreds with "\". Second, we will decide whether we need "ty" or "teen". The last one, we will use recursive until we have 3 digits of number.
Additional function that we should add, is the ability to say in either formal English (UK) or non formal English (US). The difference is only the use of "and". In UK, 110 should read "One hundred and ten", while in US, it's ok if you only say "One hundred ten". You can see the code 3 below.
Code 3 |
Public Shared Function NumberToEnglishWords(ByVal num As Long, _ ByVal level As Integer, _ Optional ByVal Official As _ Boolean = True) As String Dim retval As String = ""
Dim pInt As Long = num Mod 1000
If pInt > 99 Then retval = retval & EnglishNumber(pInt \ 100, False) & " hundred " End If
pInt = pInt Mod 100
If pInt > 0 And num \ 100 > 0 And Official = True Then retval = retval & "and " End If
If pInt > 19 Then retval = retval & EnglishNumber(pInt \ 10, True) & "ty " & _ EnglishNumber(pInt Mod 10, False) ElseIf pInt = 10 Then retval = retval & "ten" ElseIf pInt = 11 Then retval = retval & "eleven " ElseIf pInt > 11 Then retval = retval & EnglishNumber(pInt Mod 10, True) & "teen " ElseIf pInt = 12 Then retval = retval & "twelve " Else retval = retval & EnglishNumber(pInt Mod 10, False) End If
If num \ 1000 > 0 Then If num \ 1000 Mod 1000 > 0 Then retval = NumberToEnglishWords(num \ 1000, level + 1) & " " & _ EnglishLevel(level) & retval Else retval = NumberToEnglishWords(num \ 1000, level + 1) & retval End If End If
Return retval End Function
|
That's all. Just call the main function, and it will return the number in string variable. Next part, I'll explain about how to convert number to word in Indonesian Language.
You can download the code here.