B4J Question How to read a number to word

universengo

Member
Hello friends!
I am a newbje, I need your help to show me about reading a number to word.
If you have this code, please share me
Example:
121 => One hundred and twenty one
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
First 100 numbers:
B4X:
Sub Process_Globals
   Private FirstTwenty() As String = Array As String("zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", _
       "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty")
   Private Tens() As String = Array As String("", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety")
End Sub

Sub AppStart (Args() As String)
   For i = 0 To 100
       Log(NumberToWords(i))
   Next
End Sub

Sub NumberToWords(n As Int) As String
   If n >= 100 Then Return "too large"
   If n <= 20 Then Return FirstTwenty(n)
   Dim t1 As Int = Floor(n / 10)
   Dim t0 As Int = n Mod 10
   If t0 = 0 Then
       Return Tens(t1)
   End If
   Return Tens(t1) & " " & FirstTwenty(t0)
End Sub
 
Upvote 0

universengo

Member
Very good!
Thanks Erel so much!
Good luck to you!
 
Upvote 0

emexes

Expert
Licensed User
Example:
121 => One hundred and twenty one
You'll be needing to extend Erel's code to make your example work. Something like this:
B4X:
Sub BiggerNumberToWords(X)

    If X >= 5000 Then
        Return "too large"
    Else If X < -5000 Then
        Return "too small"
    End If

    Dim PlusMinus As String = ""
    If X < 0 Then
        PlusMinus = "minus "    'note trailing space to separate from number
        X = -X
    End If

    Dim Hundreds As String = ""
    If X >= 100 Then
        Hundreds = NumberToWords(Int(X / 100)) & " hundred"
    End If

    Dim Units As String = ""
    If (X Mod 100) <> 0 Or X = 0 Then
        Units = NumberToWords(X Mod 100)
    End If

    Dim Joiner As String = ""
    If Hundreds.Length <> 0 And Units.Length <> 0 Then
        Joiner = " and "
    End If

    Return PlusMinus & Hundreds & Joiner & Units

End Sub
Should work, but I haven't tested it. I remember from high school that numbers-to-words was not as easy as you'd first think. Especially in French, with their passion for number twenty.
 
Last edited:
Upvote 0

universengo

Member

Thanks emexes so much.
I am trying Erel's and your code now.
Now I know my way to work with this my question.

Your code is fix as sub'name (Sub BiggerNumberToWords(X) as string ) and delete int at "Int(X / 100))".
Perfect code:
B4X:
Sub BiggerNumberToWords(X) as string

    If X >= 5000 Then
        Return "too large"
    Else If X < -5000 Then
        Return "too small"
    End If

    Dim PlusMinus As String = ""
    If X < 0 Then
        PlusMinus = "minus "    'note trailing space to separate from number
        X = -X
    End If

    Dim Hundreds As String = ""
    If X >= 100 Then
        Hundreds = NumberToWords(X / 100) & " hundred"
    End If

    Dim Units As String = ""
    If (X Mod 100) <> 0 Or X = 0 Then
        Units = NumberToWords(X Mod 100)
    End If

    Dim Joiner As String = ""
    If Hundreds.Length <> 0 And Units.Length <> 0 Then
        Joiner = " and "
    End If

    Return PlusMinus & Hundreds & Joiner & Units

End Sub
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Mucking around during lunch break. Ideal for Green Bottles or Little Monkeys - test log is:
B4X:
1000000000000006 = One Quadrillion and Six green bottles, hanging on the wall
1000000000000005 = One Quadrillion and Five green bottles, hanging on the wall
1000000000000004 = One Quadrillion and Four green bottles, hanging on the wall
1000000000000003 = One Quadrillion and Three green bottles, hanging on the wall
1000000000000002 = One Quadrillion and Two green bottles, hanging on the wall
1000000000000001 = One Quadrillion and One green bottles, hanging on the wall
1000000000000000 = One Quadrillion green bottles, hanging on the wall
999999999999999 = Nine Hundred and Ninety-Nine Trillion, Nine Hundred and Ninety-Nine Billion, Nine Hundred and Ninety-Nine Million, Nine Hundred and Ninety-Nine Thousand, Nine Hundred and Ninety-Nine green bottles, hanging on the wall
999999999999998 = Nine Hundred and Ninety-Nine Trillion, Nine Hundred and Ninety-Nine Billion, Nine Hundred and Ninety-Nine Million, Nine Hundred and Ninety-Nine Thousand, Nine Hundred and Ninety-Eight green bottles, hanging on the wall
999999999999997 = Nine Hundred and Ninety-Nine Trillion, Nine Hundred and Ninety-Nine Billion, Nine Hundred and Ninety-Nine Million, Nine Hundred and Ninety-Nine Thousand, Nine Hundred and Ninety-Seven green bottles, hanging on the wall
999999999999996 = Nine Hundred and Ninety-Nine Trillion, Nine Hundred and Ninety-Nine Billion, Nine Hundred and Ninety-Nine Million, Nine Hundred and Ninety-Nine Thousand, Nine Hundred and Ninety-Six green bottles, hanging on the wall
from test code:
B4X:
Dim RoundAbout As Long = Power(10, 15)
Dim I As Long

For I = RoundAbout + 6 To RoundAbout - 4 Step -1
    Log(I & " = " & NumberToWords(I) & " green bottles, hanging on the wall")
Next
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
Static word lists are:
B4X:
Sub Process_Globals
     
    Dim UnitWords() As String = Array As String( _
        "", "One", "Two", "Three", "Four", _
        "Five", "Six", "Seven", "Eight", "Nine", _
        "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", _
        "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" _
    )
 
    Dim TenWords() As String = Array As String( _
        "", "Ten", "Twenty", "Thirty", "Forty", _
        "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" _
    )
 
    'only need to go up to Pentillions to handle largest Long integer, but while we're here...
    Dim ThousandWords() As String = Array As String( _
        "", "Thousand", "Million", "Billion", "Trillion", _
        "Quadrillion", "Pentillion", "Sexillion", "Septillion", "Octillion" _
    )
 
End Sub
and the associated functions are:
B4X:
Sub NumberToWords(N As Long) As String
 
    If N < 0 Then
        Return "Minus " & NumberToWordsPositive(-N)
    Else
        Return NumberToWordsPositive(N)    'including zero
    End If
 
End Sub

Sub NumberToWordsPositive(N As Long) As String
 
    If N = 0 Then
        Return "Zero"    'that gets rid of that pesky special case
    End If
 
    Dim GroupsOfThree(10) As Int
 
    Dim NumGroupsOfThree As Int = 0
 
    Do While N <> 0
        GroupsOfThree(NumGroupsOfThree) = N Mod 1000
        NumGroupsOfThree = NumGroupsOfThree + 1
     
        N = N / 1000
    Loop
 
    Dim Temp As String = ""
    For GroupOfThree = NumGroupsOfThree - 1 To 0 Step -1
        Dim ThisGroup As Int = GroupsOfThree(GroupOfThree)
     
        If ThisGroup <> 0 Then
            If Temp.Length <> 0 Then
                If GroupOfThree = 0 And ThisGroup < 100 Then
                    Temp = Temp & " and "
                Else
                    Temp = Temp & ", "
                End If
            End If
         
            Temp = Temp & NumberToWords1000(ThisGroup)
         
            If GroupOfThree <> 0 Then
                Temp = Temp & " " & ThousandWords(GroupOfThree)
            End If
        End If
    Next
 
    Return Temp

End Sub

Sub NumberToWords1000(N As Int) As String
 
    If N < 100 Then
        Return NumberToWords100(N)
    End If
 
    Dim Hundreds As String = UnitWords(N / 100) & " Hundred"    'Hundreds always non-blank since N < 100 already done
    Dim TensUnits As String = NumberToWords100(N Mod 100)    'TensUnits could be blank if digits are 00
 
    If TensUnits.Length = 0 Then
        Return Hundreds
    Else
        Return Hundreds & " and " & TensUnits
    End If
 
End Sub

Sub NumberToWords100(N As Int) As String
 
    If N < 20 Then
        Return UnitWords(N)
    End If
 
    Dim Tens As String = TenWords(N / 10)    'Tens always non-blank since N < 20 already done
    Dim Units As String = UnitWords(N Mod 10)    'Units could be blank if digit is 0
 
    If Units.Length = 0 Then
        Return Tens
    Else
        Return Tens & "-" & Units
    End If
 
End Sub
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
I think this topic can be solved.
Few things are ever fully solved ;-)

Enhancements that have occurred to me since are:

- select between British ("Four Hundred and Twenty") and American ("Four Hundred Twenty") styles
- year-style words eg Apollo 11 landing in nineteen sixty-nine, London Olympics in twenty twelve.
- billions in thousands-of-millions, eg twenty-five thousand million instead of twenty-five billion
- thousands in hundreds, eg, nineteen hundred and sixty-six instead of one thousand, nine hundred and sixty-six
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…