Results 1 to 10 of 10

Thread: Number to text

Threaded View

  1. #1

    Thread Starter
    Stack Overflow mod​erator
    Join Date
    May 2008
    Location
    British Columbia, Canada
    Posts
    2,824

    Lightbulb Number to text

    This is my first cool project in a while Everybody always makes numbers-to-text functions some time, but this one goes up to sextillions (and could handle much more than that), has proper grammar, and does irreductible fractions for you!

    Code:
    Public Function ToWords(ByVal num As Decimal) As String
            If num = 0 Then Return "Zero"
    
            Dim illions() As String = {"m", "b", "tr", "quadr", "quint", "sext"} ', "sept", "oct", "non", "dec", "undec", "dodec"} 'Go farther if you want... but you'll have to change the numerical type.
            Dim ties() As String = {"twen", "thir", "four", "fif", "six", "seven", "eight", "nine"}
            Dim nums() As String = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"}
            Dim teens() As String = {"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}
            Dim result As New System.Text.StringBuilder()
    
            If num < 0 Then
                result.Append("negative ")
                num = -num
            End If
    
            '***illions first...
            For i As Integer = illions.Length - 1 To 0 Step -1
                'They always come in threes, starting with 1000000.
                Dim d As Decimal = 1000
                For x As Integer = 0 To i
                    d *= 1000
                Next
    
                Dim n As Integer = 0
                While num >= d
                    n += 1
                    num -= d
                End While
    
                If n > 0 Then
                    result.Append(ToWords(n))
                    result.Append(" "c)
                    result.Append(illions(i))
                    result.Append("illion, ")
                End If
            Next
    
            'Then, thousands
            Dim thousands As Integer = 0
            While num >= 1000
                thousands += 1
                num -= 1000
            End While
    
            If thousands > 0 Then
                result.Append(ToWords(thousands))
                result.Append(" thousand, ")
            End If
    
            'Hundreds
            Dim hundreds As Integer = 0
            While num >= 100
                hundreds += 1
                num -= 100
            End While
    
            If hundreds > 0 Then
                result.Append(ToWords(hundreds))
                result.Append(" hundred ")
            End If
    
            'Tens
            If num >= 20 Then
                result.Append(ties(CInt(Math.Floor(num / 10)) - 2))
                result.Append("ty-")
                num -= CInt(Math.Floor(num / 10)) * 10
            End If
    
            If num < 20 AndAlso num > 10 Then
                result.Append(teens(CInt(Math.Floor(num - 10)) - 1))
                result.Append(" "c)
                num -= 10
            End If
    
            'Singles
            If Math.Floor(num) > 0 Then
                result.Append(nums(CInt(Math.Floor(num)) - 1))
                result.Append(" "c)
                num -= Math.Floor(num)
            End If
    
            'Now, the hard part - fractions.
            If num > 0 Then
                Dim numerator, denominator As Integer
                If ToFraction(num, numerator, denominator) Then
                    result.Append("and ")
                    result.Append(ToWords(numerator))
                    result.Append(" "c)
    
                    Dim ths() As String = {"half", "third", "fourth", "fifth"}
                    Dim thp() As String = {"halves", "thirds", "fourths", "fifths"}
    
                    If denominator <= ths.Length + 1 Then
                        result.Append(If(numerator = 1, ths(denominator - 2), thp(denominator - 2)))
                        result.Append(" "c)
                    Else
                        result.Append(ToWords(denominator).Replace(" "c, "-"c)) 'Fourty-millionths, not fourty millionths.
                        result.Append("th")
                        If numerator > 1 Then result.Append("s"c)
                        result.Append(" "c)
                    End If
                Else
                    result.Append("point ")
                    Do
                        num *= 10
                        result.Append(ToWords(Math.Floor(num)))
                        result.Append(" "c)
                        num -= Math.Floor(num)
                    Loop While num > 0
                End If
            End If
    
            'Some final processing
            result.Remove(result.Length - 1, 1)
            If result(result.Length - 1) = ","c Then result.Remove(result.Length - 1, 1)
    
            'Return the result
            ToWords = result.ToString().ToLower()
            ToWords = Char.ToUpper(ToWords.Chars(0)) & ToWords.Substring(1)
        End Function
    
        Public Function ToFraction(ByVal n As Decimal, ByRef numerator As Integer, ByRef denominator As Integer) As Boolean
            Try
                'We don't support 0.333333333333 = 1/3, unfortunately. :(
                numerator = Integer.Parse(n.ToString().Substring(2))
                denominator = CInt(10 ^ (n.ToString().Length - 2))
                Dim tN As Integer = numerator
                Dim tD As Integer = denominator
    
                Dim nFactors As New List(Of Integer)
                Dim dFactors As New List(Of Integer)
                For d As Integer = 2 To numerator - 1
                    While tN Mod d = 0
                        nFactors.Add(d)
                        tN \= d
                    End While
                Next
                If nFactors.Count = 0 Then nFactors.Add(numerator)
    
                For d As Integer = 2 To denominator - 1
                    While tD Mod d = 0
                        dFactors.Add(d)
                        tD \= d
                    End While
                Next
                If dFactors.Count = 0 Then dFactors.Add(denominator)
    
                Dim i As Integer
                While i < nFactors.Count
                    Dim j As Integer = dFactors.IndexOf(nFactors(i))
                    If j > -1 Then
                        dFactors.RemoveAt(j)
                        nFactors.RemoveAt(i)
                    Else
                        i += 1
                    End If
                End While
    
                numerator = nFactors.Aggregate(Function(m As Integer, o As Integer) m * o)
                denominator = dFactors.Aggregate(Function(m As Integer, o As Integer) m * o)
    
                Return True
            Catch
                Return False
            End Try
        End Function
    Last edited by minitech; May 9th, 2011 at 02:42 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width