I\'m trying to convert numbers into english words, for example 1234 would become: \"one thousand two hundred thirty four\".
My Tact
I think, I have solution that's simpler and easier to understand; it goes by slicing the number, it works up to 99 lakhs crore.
function convert_to_word(num, ignore_ten_plus_check) {
var ones = [];
var tens = [];
var ten_plus = [];
ones["1"] = "one";
ones["2"] = "two";
ones["3"] = "three";
ones["4"] = "four";
ones["5"] = "five";
ones["6"] = "six";
ones["7"] = "seven";
ones["8"] = "eight";
ones["9"] = "nine";
ten_plus["10"] = "ten";
ten_plus["11"] = "eleven";
ten_plus["12"] = "twelve";
ten_plus["13"] = "thirteen";
ten_plus["14"] = "fourteen";
ten_plus["15"] = "fifteen";
ten_plus["16"] = "sixteen";
ten_plus["17"] = "seventeen";
ten_plus["18"] = "eighteen";
ten_plus["19"] = "nineteen";
tens["1"] = "ten";
tens["2"] = "twenty";
tens["3"] = "thirty";
tens["4"] = "fourty";
tens["5"] = "fifty";
tens["6"] = "sixty";
tens["7"] = "seventy";
tens["8"] = "eighty";
tens["9"] = "ninety";
var len = num.length;
if(ignore_ten_plus_check != true && len >= 2) {
var ten_pos = num.slice(len - 2, len - 1);
if(ten_pos == "1") {
return ten_plus[num.slice(len - 2, len)];
} else if(ten_pos != 0) {
return tens[num.slice(len - 2, len - 1)] + " " + ones[num.slice(len - 1, len)];
}
}
return ones[num.slice(len - 1, len)];
}
function get_rupees_in_words(str, recursive_call_count) {
if(recursive_call_count > 1) {
return "conversion is not feasible";
}
var len = str.length;
var words = convert_to_word(str, false);
if(len == 2 || len == 1) {
if(recursive_call_count == 0) {
words = words +" rupees";
}
return words;
}
if(recursive_call_count == 0) {
words = " and " + words +" rupees";
}
var hundred = convert_to_word(str.slice(0, len-2), true);
words = hundred != undefined ? hundred + " hundred " + words : words;
if(len == 3) {
return words;
}
var thousand = convert_to_word(str.slice(0, len-3), false);
words = thousand != undefined ? thousand + " thousand " + words : words;
if(len <= 5) {
return words;
}
var lakh = convert_to_word(str.slice(0, len-5), false);
words = lakh != undefined ? lakh + " lakh " + words : words;
if(len <= 7) {
return words;
}
recursive_call_count = recursive_call_count + 1;
return get_rupees_in_words(str.slice(0, len-7), recursive_call_count) + " crore " + words;
}
Please check out my code pen
function intToEnglish(number){
var NS = [
{value: 1000000000000000000000, str: "sextillion"},
{value: 1000000000000000000, str: "quintillion"},
{value: 1000000000000000, str: "quadrillion"},
{value: 1000000000000, str: "trillion"},
{value: 1000000000, str: "billion"},
{value: 1000000, str: "million"},
{value: 1000, str: "thousand"},
{value: 100, str: "hundred"},
{value: 90, str: "ninety"},
{value: 80, str: "eighty"},
{value: 70, str: "seventy"},
{value: 60, str: "sixty"},
{value: 50, str: "fifty"},
{value: 40, str: "forty"},
{value: 30, str: "thirty"},
{value: 20, str: "twenty"},
{value: 19, str: "nineteen"},
{value: 18, str: "eighteen"},
{value: 17, str: "seventeen"},
{value: 16, str: "sixteen"},
{value: 15, str: "fifteen"},
{value: 14, str: "fourteen"},
{value: 13, str: "thirteen"},
{value: 12, str: "twelve"},
{value: 11, str: "eleven"},
{value: 10, str: "ten"},
{value: 9, str: "nine"},
{value: 8, str: "eight"},
{value: 7, str: "seven"},
{value: 6, str: "six"},
{value: 5, str: "five"},
{value: 4, str: "four"},
{value: 3, str: "three"},
{value: 2, str: "two"},
{value: 1, str: "one"}
];
var result = '';
for (var n of NS) {
if(number>=n.value){
if(number<=20){
result += n.str;
number -= n.value;
if(number>0) result += ' ';
}else{
var t = Math.floor(number / n.value);
var d = number % n.value;
if(d>0){
return intToEnglish(t) + ' ' + n.str +' ' + intToEnglish(d);
}else{
return intToEnglish(t) + ' ' + n.str;
}
}
}
}
return result;
}
I know this problem had solved 3 years ago. I am posting this SPECIALLY FOR INDIAN DEVELOPERS
After spending some time in googling and playing with others code i made a quick fix and reusable function works well for numbers upto 99,99,99,999. use : number2text(1234.56);
will return ONE THOUSAND TWO HUNDRED AND THIRTY-FOUR RUPEE AND FIFTY-SIX PAISE ONLY
. enjoy !
function number2text(value) {
var fraction = Math.round(frac(value)*100);
var f_text = "";
if(fraction > 0) {
f_text = "AND "+convert_number(fraction)+" PAISE";
}
return convert_number(value)+" RUPEE "+f_text+" ONLY";
}
function frac(f) {
return f % 1;
}
function convert_number(number)
{
if ((number < 0) || (number > 999999999))
{
return "NUMBER OUT OF RANGE!";
}
var Gn = Math.floor(number / 10000000); /* Crore */
number -= Gn * 10000000;
var kn = Math.floor(number / 100000); /* lakhs */
number -= kn * 100000;
var Hn = Math.floor(number / 1000); /* thousand */
number -= Hn * 1000;
var Dn = Math.floor(number / 100); /* Tens (deca) */
number = number % 100; /* Ones */
var tn= Math.floor(number / 10);
var one=Math.floor(number % 10);
var res = "";
if (Gn>0)
{
res += (convert_number(Gn) + " CRORE");
}
if (kn>0)
{
res += (((res=="") ? "" : " ") +
convert_number(kn) + " LAKH");
}
if (Hn>0)
{
res += (((res=="") ? "" : " ") +
convert_number(Hn) + " THOUSAND");
}
if (Dn)
{
res += (((res=="") ? "" : " ") +
convert_number(Dn) + " HUNDRED");
}
var ones = Array("", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX","SEVEN", "EIGHT", "NINE", "TEN", "ELEVEN", "TWELVE", "THIRTEEN","FOURTEEN", "FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN","NINETEEN");
var tens = Array("", "", "TWENTY", "THIRTY", "FOURTY", "FIFTY", "SIXTY","SEVENTY", "EIGHTY", "NINETY");
if (tn>0 || one>0)
{
if (!(res==""))
{
res += " AND ";
}
if (tn < 2)
{
res += ones[tn * 10 + one];
}
else
{
res += tens[tn];
if (one>0)
{
res += ("-" + ones[one]);
}
}
}
if (res=="")
{
res = "zero";
}
return res;
}
This is a simple ES6+ number to words function. You can simply add 'illions' array to extend digits. American English version. (no 'and' before the end)
// generic number to words
let digits = ['','one','two','three','four', 'five','six','seven','eight','nine','ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen'];
let ties = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
let illions = ['', 'thousand', 'million', 'billion', 'trillion'].reverse()
let join = (a, s) => a.filter(v => v).join(s || ' ')
let tens = s =>
digits[s] ||
join([ties[s[0]], digits[s[1]]], '-') // 21 -> twenty-one
let hundreds = s =>
join(
(s[0] !== '0' ? [digits[s[0]], 'hundred'] : [])
.concat( tens(s.substr(1,2)) ) )
let re = '^' + '(\\d{3})'.repeat(illions.length) + '$'
let numberToWords = n =>
// to filter non number or '', null, undefined, false, NaN
isNaN(Number(n)) || !n && n !== 0
? 'not a number'
: Number(n) === 0
? 'zero'
: Number(n) >= 10 ** (illions.length * 3)
? 'too big'
: String(n)
.padStart(illions.length * 3, '0')
.match(new RegExp(re))
.slice(1, illions.length + 1)
.reduce( (a, v, i) => v === '000' ? a : join([a, hundreds(v), illions[i]]), '')
// just for this question.
let update = () => {
let value = document.getElementById('number').value
document.getElementById('container').innerHTML = numberToWords(value)
}
Your problem is already solved but I am posting another way of doing it just for reference.
The code was written to be tested on node.js, but the functions should work fine when called within the browser. Also, this only handles the range [0,1000000], but can be easily adapted for bigger ranges.
// actual conversion code starts here
var ones = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
var tens = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'];
var teens = ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'];
function convert_millions(num) {
if (num >= 1000000) {
return convert_millions(Math.floor(num / 1000000)) + " million " + convert_thousands(num % 1000000);
} else {
return convert_thousands(num);
}
}
function convert_thousands(num) {
if (num >= 1000) {
return convert_hundreds(Math.floor(num / 1000)) + " thousand " + convert_hundreds(num % 1000);
} else {
return convert_hundreds(num);
}
}
function convert_hundreds(num) {
if (num > 99) {
return ones[Math.floor(num / 100)] + " hundred " + convert_tens(num % 100);
} else {
return convert_tens(num);
}
}
function convert_tens(num) {
if (num < 10) return ones[num];
else if (num >= 10 && num < 20) return teens[num - 10];
else {
return tens[Math.floor(num / 10)] + " " + ones[num % 10];
}
}
function convert(num) {
if (num == 0) return "zero";
else return convert_millions(num);
}
//end of conversion code
//testing code begins here
function main() {
var cases = [0, 1, 2, 7, 10, 11, 12, 13, 15, 19, 20, 21, 25, 29, 30, 35, 50, 55, 69, 70, 99, 100, 101, 119, 510, 900, 1000, 5001, 5019, 5555, 10000, 11000, 100000, 199001, 1000000, 1111111, 190000009];
for (var i = 0; i < cases.length; i++) {
console.log(cases[i] + ": " + convert(cases[i]));
}
}
main();
I am providing here my solution for converting numbers to the equivalent English words using the Single Loop String Triplets (SLST) Method which I have published and explained in detail here at Code Review with illustration graphics.
Simple Number to Words using a Single Loop String Triplets in JavaScript
The concept is simple and easily coded and is also very efficient and fast. The code is very short compared with other alternative methods described in this article.
The concept also permits the conversion of very vary large numbers as it does not rely on using the numeric/math function of the language and therefore avoids any limitations.
The Scale Array may be increased by adding more scale names if required after "Decillion".
A sample test function is provided below to generate numbers from 1 to 1099 as an example.
A full fancy version is available that caters for adding the word "and" and commas between the scales and numbers to align with the UK and US ways of spelling the numbers.
Hope this is useful.
/************************************************************/
function NumToWordsInt(NumIn) {
/************************************************************
* Convert Integer Numbers to English Words
* Using the Single Loop String Triplets Method
* @Param : {Number} The number to be converted
* For large numbers use a string
* @Return: {String} Wordified Number (Number in English Words)
* @Author: Mohsen Alyafei 10 July 2019
* @Notes : Call separately for whole and for fractional parts.
* Scale Array may be increased by adding more scale
* names if required after Decillion.
/************************************************************/
if (NumIn==0) return "Zero";
var Ones = ["", "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"],
Scale = ["", "Thousand", "Million", "Billion", "Trillion", "Quadrillion", "Quintillion", "Sextillion", "Septillion", "Octillion", "Nonillion", "Decillion"],
N1, N2, Sep, j, i, h, Trplt, tns="", NumAll = "";
NumIn += ""; // Make NumIn a String
//----------------- code starts -------------------
NumIn = "0".repeat(NumIn.length * 2 % 3) + NumIn; //Create shortest string triplets 0 padded
j = 0; //Start with the highest triplet from LH
for (i = NumIn.length / 3 - 1; i >= 0; i--) { //Loop thru number of triplets from LH most
Trplt = NumIn.substring(j, j + 3); //Get a triplet number starting from LH
if (Trplt !="000") { //Skip empty trplets
Sep = Trplt[2] !="0" ? "-":" "; //Dash only for 21 to 99
N1 = Number(Trplt[0]); //Get Hundreds digit
N2 = Number(Trplt.substr(1)); //Get 2 lowest digits (00 to 99)
tns = N2 > 19 ? Tens[Number(Trplt[1])] + Sep + Ones[Number(Trplt[2])] : Ones[N2];
NumAll += ((h = N1>0 ? Ones[N1] + " Hundred": "") + " " + tns).trim() + " " + Scale[i]+ " ";
}
j += 3; //Next lower triplets (move to RH)
}
//----------------- code Ends --------------------
return NumAll.trim(); //Return trimming excess spaces if any
}
// ----------------- test sample -----------------
console.log(NumToWordsInt(67123))
console.log(NumToWordsInt(120003123))
console.log(NumToWordsInt(123999))
console.log(NumToWordsInt(789123))
console.log(NumToWordsInt(100178912))
console.log(NumToWordsInt(777))
console.log(NumToWordsInt(999999999))
console.log(NumToWordsInt(45))