How to convert numbers from 0 to 999,999,999,999,999 (up to 999 trillion) into English words in Swift

1 Answer

0 votes
import Foundation

/*
    Convert numbers to English words in Swift
    -----------------------------------------
    Supports numbers from 0 to 999,999,999,999,999.

    Strategy:
    - Break the number into named groups: trillions, billions, millions,
      thousands, hundreds.
    - Convert each 0–999 group using a helper function.
    - Append group names ("trillion", "billion", etc.) when needed.
    - Build the final string using an array and joined(separator:) for efficiency.
*/

private let ones: [String] = [
    "zero", "one", "two", "three", "four",
    "five", "six", "seven", "eight", "nine",
    "ten", "eleven", "twelve", "thirteen", "fourteen",
    "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
]

private let tensWords: [String] = [
    "", "", "twenty", "thirty", "forty",
    "fifty", "sixty", "seventy", "eighty", "ninety"
]

/*
    appendWord:
    Adds a word to the output array.
*/
private func appendWord(_ out: inout [String], _ word: String) {
    if !word.isEmpty {
        out.append(word)
    }
}

/*
    convertHundreds:
    Converts numbers from 0 to 999 into words.
*/
private func convertHundreds(_ n0: Int64, _ out: inout [String]) {
    var n = n0

    if n == 0 { return }

    if n >= 100 {
        appendWord(&out, ones[Int(n / 100)])
        appendWord(&out, "hundred")
        n %= 100
        if n > 0 { appendWord(&out, "and") }
    }

    if n >= 20 {
        appendWord(&out, tensWords[Int(n / 10)])
        if n % 10 != 0 {
            appendWord(&out, ones[Int(n % 10)])
        }
    } else if n > 0 {
        appendWord(&out, ones[Int(n)])
    }
}

/*
    numberToWords:
    Converts any number from 0 to 999,999,999,999,999 into English words.
*/
func numberToWords(_ num: Int64) -> String {
    if num == 0 { return "zero" }

    var out: [String] = []

    let trillions: Int64 = num / 1_000_000_000_000
    let billions: Int64  = (num / 1_000_000_000) % 1000
    let millions: Int64  = (num / 1_000_000) % 1000
    let thousands: Int64 = (num / 1_000) % 1000
    let hundreds: Int64  = num % 1000

    if trillions > 0 {
        convertHundreds(trillions, &out)
        appendWord(&out, "trillion")
    }

    if billions > 0 {
        convertHundreds(billions, &out)
        appendWord(&out, "billion")
    }

    if millions > 0 {
        convertHundreds(millions, &out)
        appendWord(&out, "million")
    }

    if thousands > 0 {
        convertHundreds(thousands, &out)
        appendWord(&out, "thousand")
    }

    if hundreds > 0 {
        convertHundreds(hundreds, &out)
    }

    return out.joined(separator: " ")
}

/*
    main:
    Demonstrates usage with multiple test numbers.
*/
let tests: [Int64] = [
    1_234,
    12_345,
    123_456,
    1_234_567,
    123_456_789,
    12_345_678_901,
    1_234_567_890_123,
    999_999_999_999_999
]

for n in tests {
    print("\(n) -> \(numberToWords(n))")
}


/*
run:

1234 -> one thousand two hundred and thirty four
12345 -> twelve thousand three hundred and forty five
123456 -> one hundred and twenty three thousand four hundred and fifty six
1234567 -> one million two hundred and thirty four thousand five hundred and sixty seven
123456789 -> one hundred and twenty three million four hundred and fifty six thousand seven hundred and eighty nine
12345678901 -> twelve billion three hundred and forty five million six hundred and seventy eight thousand nine hundred and one
1234567890123 -> one trillion two hundred and thirty four billion five hundred and sixty seven million eight hundred and ninety thousand one hundred and twenty three
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

*/

 



answered Sep 6 by avibootz

Related questions

...