This is a little programming exercise, purely for fun. The idea is to take a number (in digits) and convert it into it’s english form. So, e.g. 1000 becomes “one thousand”, 1450 becomes “one thousand, four hundred fifty” and so on…
The approach I’ve taken is as follows :-
- Deal with numbers less than hundred separately, which checks is number is less than 20 or not and converts it into english accordingly.
- Deal with numbers less than thousand separately, as we need to deal with hundreds here.
- Deal with the rest in a generic loop, as it’s all multiples of thousands from now on.
I ended up writing the code in Coffeescript for this one, it just makes it easier sometimes. Here is the code :-
[js]class @NumberToWords
ones = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
tens = ["twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
scales = ["", "thousand", "million", "billion", "trillion", "quadrillion", "quintillion"]
convert: (num) ->
number = Math.abs(num)
return @check_negative(num, @convert_less_than_hundred number) if number < 100
return @check_negative(num, @convert_less_than_thousand number) if number < 1000
for n in [0..scales.length]
previousScale = n – 1
scaleValue = Math.pow(1000, n)
if scaleValue > number
previousScaleValue = Math.pow(1000, previousScale)
numberPart = parseInt(number / previousScaleValue, 10)
remainder = number – (numberPart * previousScaleValue)
word = @convert_less_than_thousand(numberPart) + " " + scales[previousScale]
if remainder > 0
word = word + ", " + @convert(remainder);
return @check_negative(num, word)
convert_less_than_hundred: (number) ->
return ones[number] if number < 20
for i in [0..tens.length]
tempVal = 20 + 10 * i
if tempVal + 10 > number
if (number % 10 != 0)
return tens[i] + " " + ones[number % 10]
return tens[i]
convert_less_than_thousand: (number) ->
word = ""
remainder = parseInt(number / 100, 10)
modulus = parseInt(number % 100, 10)
if remainder > 0
word = ones[remainder] + " hundred"
if modulus > 0
word = word + " "
if modulus > 0
word = word + @convert_less_than_hundred modulus
word
check_negative: (number, word) ->
return if number < 0 then "negative " + word else word[/js]
And to call it, just do this (once the script is loaded on the page, of-course):-
[js]<script src="num2words.js"></script>
var num2words = new NumberToWords();
num2words.convert(850); //’eight hundred fifty’
num2words.convert(8500); //’eight thousand, five hundred’
num2words.convert(85000); //’eighty five thousand’
num2words.convert(850000); //’eight hundred fifty thousand’
num2words.convert(8500000); //’eight million, five hundred thousand’
and so on……
</script>[/js]
Both the Coffeescript and the generated Javascript are available on this Gist here. Feel free to suggest improvements/refactoring to the code above.
Neat.
A fairly common interview question.
Indeed!
what about negative numbers
That’s covered as well. Check the code, there is a check_negative function.
but I couldn’t print 1,2,3,4 to One, two , three , four . and so on.
1,2,3,4 is not a number
how can i convert numbers something like 2365.87 ???
This code doesn’t cover decimal points but can be extended to do so.