Task

Show how to spell out a number in English.

You can use a preexisting implementation or roll your own, but you should support inputs up to at least one million (or the maximum value of your language's default bounded integer type, if that's less).

Support for inputs other than positive integers (like zero, negative integers, and floating-point numbers) is optional.



Related task

   Spelling of ordinal numbers.


 
fn numToEng num =
(
	num = num as integer -- convert to int
	local originalNumber = num -- store the initial value, to check if it was negative afterwards
 
	num = abs num -- make positive
	local numStr = num as string -- store as string to check the length
 
	local nonFirstDigits = (if numStr.count > 3 then ((substring numStr ((if mod numStr.count 3 ==0 then 3 else mod numStr.count 3)+1) -1)) else "0") -- this is the string of the number without the beginning, i.e 123456 will give 456, 12035 will give 2035
	local singleDigits = #("One","Two","Three","Four","Five","Six","Seven","Eight","Nine")
	local ElevenTwenty = #("Eleven","Twelve","Thirteen","Fourteen","Fifteen","Sixteen","Seventeen","Eighteen","Nineteen")
	local tens = #("Ten","Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety")
	local big = #("Hundred","Thousand","Million","Billion")
	local ret = "" -- this is the value to be returned
 
	case of
	(
		(num == 0 ): ret += "Zero" -- number is zero
		(num < 10): ret += singleDigits[num] -- number is not and smaller than 10
		(num == 10): ret += tens[1] -- number is 10
		(num < 20): ret += elevenTwenty[abs(10-num)] -- number is between 11 and 19
		(num <= 90 and mod num 10 == 0): ret += tens[num/10] -- number is >= 20 and <= 90 and is dividable by 10
		(num < 100): ret += (numToEng (floor(num/10.0)*10) +" "+ numtoEng (num-(floor(num/10.0))*10)) -- number is >= 20, < 100 and is not dividable by 10
		(num < 1000): ret += (singledigits[floor(num/100) as integer] + " "+big[1]+ (if mod num 100 != 0 then (" and "+numtoeng (num-(floor(num/100.0)*100))) else "")) -- number is >= 100, < 1000 
		(num >= 1000): ret += -- number is >= 1000
			(
				numtoeng (substring numStr 1 (if mod numStr.count 3 ==0 then 3 else mod numStr.count 3)) + \
				" " + big[1+((numStr.count-1)/3)] + (if nonFirstDigits as integer == 0 then "" else (if nonFirstDigits as integer < 100 then " and " else ", ")) + \
				(if (mod num 1000 == 0) then "" else (numtoeng nonFirstDigits))
 
			)
	)
 
	if originalNumber < 0 and (substring ret 1 8) != "Negative" do ret = ("Negative "+ret) -- if number is negative 
	ret = (toupper ret[1]) + (tolower (substring ret 2 -1)) -- make the first char uppercase and rest lowercase
	return ret
)