Numbers to words

A bit of code I made in VB.NET to convert the digit form of integers into words.

I've intentionally assumed that inputs will match the desired format since the focus of this task for me was to appropriately handle the logic required to complete such a task from valid input. Due to this, there is no error checking built into my getInputNumber function.

I'd appreciate any feedback on this.

Module NumberToWords

Sub Main()
Do While (True)
Dim inputNumber As String = getInputNumber()

Console.WriteLine(convertNumberToWords(inputNumber))
Loop
End Sub

Function getInputNumber() As String
Console.WriteLine("Enter a number:")

End Function

Function convertNumberToWords(ByVal inputString As String) As String
Const DIGITS_IN_HUNDRED As UInt16 = 3

' Add leading zeros so that number of digits is a multiple of 3.
Do While (inputString.Length Mod DIGITS_IN_HUNDRED <> 0)
inputString = "0" & inputString
Loop

Dim resultString As String = ""

' Process each set of 3 digits in the number, then add the appropriate magnitude indicator at the end (e.g. billion).
For i = 0 To inputString.Length - 1 Step 3
Dim hundreds As String = inputString(i)
Dim tens As String = inputString(i + 1)
Dim units As String = inputString(i + 2)

If (hundreds <> "0" OrElse tens <> "0" OrElse units <> "0") Then
' If this isn't the first set of three non-zero digits that has been processed.
If (resultString <> "") Then
' Condition ensures that 1001 produces "one thousand and one" rather than "one thousand, one", for example.
If (inputString.Length - 1 - i < 3 AndAlso hundreds = "0") Then
resultString &= " and "
Else
' Comma for readability.
resultString &= ", "
End If
End If

resultString &= convertThreeDigitNumberToWords(hundreds, tens, units)

resultString &= " " & getMagnitudeName(inputString.Length - i - 3)
End If
Next

If (resultString = " ") Then
resultString = "zero"
End If

Return resultString
End Function

Function convertThreeDigitNumberToWords(ByVal hundreds As UInt16, ByVal tens As UInt16, ByVal units As UInt16) As String
Dim resultString As String = ""

If (hundreds <> "0") Then
resultString = getDigitName(hundreds) & " hundred"

' If there is a non-zero value for the tens or units, add an "and".
' Use to produce 'four hundred and fifty two', rather than 'four hundred fifty two'
If (tens <> "0" OrElse units <> "0") Then
resultString &= " and "
End If
End If

If (tens <> "0" OrElse units <> "0") Then
' Two digit numbers beginning with 1 are special cases (11 spoken eleven, rather than "ten one", for example).
' It won't matter if the number begins with "0" after it has been converted to an integer.
If (tens = "1" OrElse tens = "0") Then
resultString &= getDigitName(tens & units)
Else
resultString &= getDigitName(tens & "0")

If (units <> "0") Then
resultString &= " " & getDigitName(units)
End If
End If
End If

Return resultString
End Function

Function getMagnitudeName(ByVal digitPlace As UInt16) As String
' The power associated with the highest named number I could find with 10^(power of divisible by 3) (a vigintillion)
Const MAXIMUM_NUMBER_NAME As UInt16 = 63

Dim resultString As String = ""

Do Until (digitPlace = 0)
Dim magnitudeValue As UInt16

If (digitPlace Mod MAXIMUM_NUMBER_NAME <> 0) Then
magnitudeValue = digitPlace Mod MAXIMUM_NUMBER_NAME
Else
magnitudeValue = MAXIMUM_NUMBER_NAME
End If

Select Case magnitudeValue
Case 3
resultString &= "thousand"
Case 6
resultString &= "million"
Case 9
resultString &= "billion"
Case 12
resultString &= "trillion"
Case 15
Case 18
resultString &= "quintillion"
Case 21
resultString &= "sextillion"
Case 24
resultString &= "septillion"
Case 27
resultString &= "octillion"
Case 30
resultString &= "nonillion"
Case 33
resultString &= "decillion"
Case 36
resultString &= "undecillion"
Case 39
resultString &= "duodecillion"
Case 42
resultString &= "tredecillion"
Case 45
resultString &= "quattuordecillion"
Case 48
resultString &= "quindecillion"
Case 51
resultString &= "sexdecillion"
Case 54
resultString &= "septendecillion"
Case 57
resultString &= "octodecillion"
Case 60
resultString &= "novemdecillion"
Case 63
resultString &= "vigintillion"
End Select

digitPlace -= magnitudeValue

If (digitPlace <> 0) Then
resultString &= " "
End If
Loop

Return resultString
End Function

Function getDigitName(ByVal digit As UInt16) As String
Select Case digit
Case 0
Return "zero"
Case 1
Return "one"
Case 2
Return "two"
Case 3
Return "three"
Case 4
Return "four"
Case 5
Return "five"
Case 6
Return "six"
Case 7
Return "seven"
Case 8
Return "eight"
Case 9
Return "nine"
Case 10
Return "ten"
Case 11
Return "eleven"
Case 12
Return "twelve"
Case 13
Return "thirteen"
Case 14
Return "fourteen"
Case 15
Return "fifteen"
Case 16
Return "sixteen"
Case 17
Return "seventeen"
Case 18
Return "eighteen"
Case 19
Return "nineteen"
Case 20
Return "twenty"
Case 30
Return "thirty"
Case 40
Return "forty"
Case 50
Return "fifty"
Case 60
Return "sixty"
Case 70
Return "seventy"
Case 80
Return "eighty"
Case 90
Return "ninety"
End Select

Return ""
End Function
End Module

Just a few remarks

Naming

Based on the .NET naming guidelines methods should be named using PascalCase casing. Although VB isn't case sensitive it is a good habit to stick to conventions of the language you are using.

Strings

Because strings are immutable each time you use a line like inputString = "0" & inputstring will result in a new string object. This is quit slow. It is best practice to use a StringBuilder especially if you concat strings in a loop.

Instead of using this Do While loop

Do While (inputString.Length Mod DIGITS_IN_HUNDRED <> 0)
inputString = "0" & inputString
Loop

you should take advantage of the String.PadLeft() method provided by the NET framework.