Converts longs > Long.MinValue to words. The code uses recursion FWIW.
Code:Public Class NumberToWords ''' <summary> ''' Convert any Long (except Long.MinValue) to words ''' </summary> ''' <param name="someNum">the number to be converted</param> ''' <param name="negativePrefix">the prefix to use if the number is negative</param> ''' <returns>string representation of number</returns> ''' <remarks>won't convert Long.MinValue</remarks> Public Shared Function Convert(someNum As Long, Optional negativePrefix As String = "negative") As String 'convert using NumToString Return NumToString(someNum, 0, negativePrefix) End Function Private Shared Function NumToString(num As Long, level As Integer, Optional negativeprfx As String = "") As String 'on entry level represents the recursive depth 'Debug.Write(level & " ") Dim rv As New System.Text.StringBuilder Dim workingNum As Long = num 'working number Const appender As String = ", " Const entyAppender As String = "-" 'for hyphens on the 'entys 20, 30, 40, etc 'for this to work the number must be positive 'and greater than Long.MinValue If workingNum = Long.MinValue Then Throw New ArgumentException("Can't convert Long.MinValue") End If 'the negative, if any is 'fixed at the end Dim isNeg As Boolean = False If workingNum < 0L Then isNeg = True workingNum = -workingNum 'convert to positive if needed 'or 'old school 'reverse the bits and add one 'workingNum = workingNum Xor &HFFFFFFFFFFFFFFFFL 'workingNum += 1L End If 'is the number known? rv.Append(Defined(workingNum)) If rv.Length = 0 Then 'known? 'no 'the groups defined as long 'so that the results don't have to be converted Dim ones As Long = 0L Dim tens As Long = 0L Dim hundreds As Long = 0L Dim thousands As Long = 0L Dim millions As Long = 0L Dim billions As Long = 0L Dim trillions As Long = 0L Dim quadrillions As Long = 0L Dim quintillions As Long = 0L 'get count of each grouping 'decreasing workingNum by the grouping total 'only during the first call to this method 'can the number be > 999 If level = 0 Then quintillions = workingNum \ NumWords.quintillion workingNum -= quintillions * NumWords.quintillion quadrillions = workingNum \ NumWords.quadrillion workingNum -= quadrillions * NumWords.quadrillion trillions = workingNum \ NumWords.trillion workingNum -= trillions * NumWords.trillion billions = workingNum \ NumWords.billion workingNum -= billions * NumWords.billion millions = workingNum \ NumWords.million workingNum -= millions * NumWords.million thousands = workingNum \ NumWords.thousand workingNum -= thousands * NumWords.thousand 'now check each group 'and recursively call 'on the groups amount which will be < 1000 If quintillions > 0L Then rv.Append(NumToString(quintillions, level + 1)) rv.Append(" ") rv.Append(NumWords.quintillion.ToString) rv.Append(appender) End If If quadrillions > 0L Then rv.Append(NumToString(quadrillions, level + 1)) rv.Append(" ") rv.Append(NumWords.quadrillion.ToString) rv.Append(appender) End If If trillions > 0L Then rv.Append(NumToString(trillions, level + 1)) rv.Append(" ") rv.Append(NumWords.trillion.ToString) rv.Append(appender) End If If billions > 0L Then rv.Append(NumToString(billions, level + 1)) rv.Append(" ") rv.Append(NumWords.billion.ToString) rv.Append(appender) End If If millions > 0L Then rv.Append(NumToString(millions, level + 1)) rv.Append(" ") rv.Append(NumWords.million.ToString) rv.Append(appender) End If If thousands > 0L Then rv.Append(NumToString(thousands, level + 1)) rv.Append(" ") rv.Append(NumWords.thousand.ToString) rv.Append(appender) End If End If hundreds = workingNum \ NumWords.hundred workingNum -= hundreds * NumWords.hundred 'special case for tens 'if the number is less than 20 'don't bother dividing by ten 'because all numbers less than 20 are defined 'note: 20 is known but should be treated as a ten If workingNum > 19L Then tens = workingNum \ NumWords.ten workingNum -= tens * NumWords.ten End If ones = workingNum 'what is left If hundreds > 0L Then rv.Append(NumToString(hundreds, level + 1)) rv.Append(" ") rv.Append(NumWords.hundred.ToString) rv.Append(" ") End If If tens > 0L Then 'the tens (10, 20, 30 ...) are defined rv.Append(NumToString(tens * NumWords.ten, level + 1)) ' times ten to get the defined number string rv.Append(entyAppender) End If If ones > 0L Then rv.Append(NumToString(ones, level + 1)) rv.Append(" ") End If End If 'known numbers come directly here 'was the number negative? If isNeg Then If negativeprfx.Length <> 1 Then rv.Insert(0, " ") rv.Insert(0, negativeprfx) Else rv.Insert(0, negativeprfx) End If End If 'get rid of trailing spaces and hyphens, if any Return rv.ToString.TrimEnd(appender.ToCharArray).TrimEnd(entyAppender.ToCharArray) End Function Private Shared Function Defined(num As Long) As String 'is the number defined and less than 100 If [Enum].IsDefined(GetType(NumWords), num) AndAlso num < 100L Then 'yes Return [Enum].GetName(GetType(NumWords), num) Else 'no Return "" End If End Function Enum NumWords As Long zero = 0L one = 1L two = 2L three = 3L four = 4L five = 5L six = 6L seven = 7L eight = 8L nine = 9L ten = 10L eleven = 11L twelve = 12L thirteen = 13L fourteen = 14L fifteen = 15L sixteen = 16L seventeen = 17L eightteen = 18L nineteen = 19L twenty = 20L thirty = 30L forty = 40L fifty = 50L sixty = 60L seventy = 70L eighty = 80L ninety = 90L hundred = 100L thousand = 1000L million = 1000000L billion = 1000000000L trillion = 1000000000000L quadrillion = 1000000000000000L quintillion = 1000000000000000000L End Enum End Class


Reply With Quote
