Skip to main content
1 of 12
Mohsen Alyafei
  • 599
  • 3
  • 5
  • 19

Number to Words in JavaScript using a Single Loop String Triplets

For a start, I am new to JavaScript.

I have reviewed 2 extensive articles https://stackoverflow.com/questions/14766951/convert-digits-into-words-with-javascript and https://stackoverflow.com/questions/5529934/javascript-numbers-to-words and the answers therein using various methods for spelling a number into words in English.

I have tried to come-up with simple method using a single loop and avoid the use of excessive arithmetic, switches, array manipulations, reversing or splitting strings, or recursion.

The principle applied here is to follow the human reading logic of pronouncing and writing the number (in US English) from Left to Right using the standard US English (i.e. without an “and” after the hundred parts).

The function is made to work for whole numbers (integers). But may be called twice for whole and fractional parts after a number split at the decimal point.

Also currency and sub-currency words could be added easily if a whole/fractional split is made.

It is not intended for the function to do everything or check everying as this could be left to a another higher function that will call this function, therefore the following are not accounted for for simplicity:

  • No checks for negative numbers.
  • No checks for non-number (NaN) strings/data.
  • No checks or conversion for exponantional notations.

However, large numbers can be passed as a String if necessary.

The “Scale” Array may be increased by adding additional scales above “Decillion”.

It is simple to add a Comma "," after each scale words (execpt last) as some would prefer that.

Here how it works with an example:

Example Number: 1223000789

One Billion Two Hundred Twenty-Three Million Seven Hundred Eighty-Nine.

1. Stringfy and convert to shortest triplets padded with zero:

NumIn = "0".repeat(NumIn.length * 2 % 3) + NumIn;

The stringfied Number in Triplets is now (2 zeros added to the LH):

001223000789

In other words the number is now: enter image description here

In our example, no triplets exist for scales above Billions, so no Trillions or above num scales.

2. Get count of Triplets: in this case 4 Triplets (i.e. count 3 to 0):

Triplets = NumIn.length / 3 - 1

3. Loop starting from the Most Significant Triplet (MST) (i.e. like you read the number) and:

(a) Convert each Triplet number to words (1 to 999) and add the scale name after it.

(b) If a triplet is empty (i.e. 000) then skip it.

(c) Join the new Triplet words to the end of the previous one.

Line 7 of the code ensures a hyphen is inserted for numbers between 21 to 99 in accordance with English numerals writing (i.e. Twenty-One, Fifty-Seven, etc.). You could delete that if it does not apply to you together with the associated variable declartion.

Graphical Example of the above:

enter image description here

Result:

One Billion Two Hundred Twenty-Three Million Seven Hundred Eighty-Nine.

I have found this to be the simplist method to understand and code.

I have also coded the same function in VBA.

I would like the code to be reviewed for any bugs, optimisation, or improvements. I am sure there is room for improvements and corrections.

Thanks in advance to all, your valuable inputs and feedback apprciated.

Mohsen Alyafei

function NumToWordsInt(NumIn) {
//---------------------------------------
//Convert Integer Number to English Words
//Using a Loop String Triplets
//Mohsen Alyafei 10 July 2019
//Call ir for a whole number and fractional separately
//---------------------------------------

 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"];
 var  Tens = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"];
 var Scale = ["", "Thousand", "Million", "Billion", "Trillion", "Quadrillion", "Quintillion", "Sextillion", "Septillion", "Octillion", "Nonillion", "Decillion"];
 var N1, N2, Sep, L, j, i, h,Trplt,tns="", NumAll = "";
 NumIn += "";                                            //NumIn=NumIn.toString()
//----------------- code start -------------------
 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 triplets
        h = ""; //Init hundreds                          //-------inner code for 3 digit starts
        Trplt[2] != "0" ? Sep="-":Sep=" ";               //Only if hyphen needed for nums 21 to 99
        N1 = Number(Trplt[0]);                           //Get Hundreds digit
        N2 = Number(Trplt.substr(1));                    //Get 2 lowest digits (00 to 99) 
        N2 > 19 ? tns = Tens[Number(Trplt[1])] + Sep + Ones[Number(Trplt[2])]:tns = Ones[N2]
        if (N1 > 0) h = Ones[N1] + " Hundred"            //Add " hundred" if needed
        Trplt = (h + " " + tns).trim() + " " + Scale[i]; //Create number with scale ----inner code ends
        NumAll = NumAll + Trplt + " ";                   //join the triplets scales to previous
      }
      j += 3;                                            //Go for next lower triplets (move to RH)
    }
//----------------- code end --------------------- 
 return NumAll.trim();                                   //Return trimming excess spaces
}
//
//
//================= for testing ================

document.getElementById('number').onkeyup = function () {
    document.getElementById('words').innerHTML = NumToWordsInt(document.getElementById('number').value);
};
<span id="words"></span>
<input id="number" type="text" />

Mohsen Alyafei
  • 599
  • 3
  • 5
  • 19