I’m trying to convert numbers into english words, for example 1234 would become: “one thousand two hundred thirty four“.
My Tactic goes like this:
Separate the digits to three and put them on Array (
finlOutPut
), from right to left.Convert each group (each cell in the
finlOutPut
array) of three digits to a word (this what thetriConvert
function does). If all the three digits are zero convert them to"dontAddBigSuffix"
From Right to left, add thousand, million, billion, etc. If the
finlOutPut
cell equals"dontAddBigSufix"
(because it was only zeroes), don’t add the word and set the cell to" "
(nothing).
It seems to work pretty well, but I’ve got some problems with numbers like 190000009, converted to: “one hundred ninety million“. Somehow it “forgets” the last numbers when there are a few zeros.
What did I do wrong? Where is the bug? Why does it not work perfectly?
function update(){ var bigNumArry = new Array('', ' thousand', ' million', ' billion', ' trillion', ' quadrillion', ' quintillion'); var output = ''; var numString = document.getElementById('number').value; var finlOutPut = new Array(); if (numString == '0') { document.getElementById('container').innerHTML = 'Zero'; return; } if (numString == 0) { document.getElementById('container').innerHTML = 'messeg tell to enter numbers'; return; } var i = numString.length; i = i - 1; //cut the number to grups of three digits and add them to the Arry while (numString.length > 3) { var triDig = new Array(3); triDig[2] = numString.charAt(numString.length - 1); triDig[1] = numString.charAt(numString.length - 2); triDig[0] = numString.charAt(numString.length - 3); var varToAdd = triDig[0] + triDig[1] + triDig[2]; finlOutPut.push(varToAdd); i--; numString = numString.substring(0, numString.length - 3); } finlOutPut.push(numString); finlOutPut.reverse(); //conver each grup of three digits to english word //if all digits are zero the triConvert //function return the string "dontAddBigSufix" for (j = 0; j < finlOutPut.length; j++) { finlOutPut[j] = triConvert(parseInt(finlOutPut[j])); } var bigScalCntr = 0; //this int mark the million billion trillion... Arry for (b = finlOutPut.length - 1; b >= 0; b--) { if (finlOutPut[b] != "dontAddBigSufix") { finlOutPut[b] = finlOutPut[b] + bigNumArry[bigScalCntr] + ' , '; bigScalCntr++; } else { //replace the string at finlOP[b] from "dontAddBigSufix" to empty String. finlOutPut[b] = ' '; bigScalCntr++; //advance the counter } } //convert The output Arry to , more printable string for(n = 0; n<finlOutPut.length; n++){ output +=finlOutPut[n]; } document.getElementById('container').innerHTML = output;//print the output } //simple function to convert from numbers to words from 1 to 999 function triConvert(num){ var ones = new Array('', ' one', ' two', ' three', ' four', ' five', ' six', ' seven', ' eight', ' nine', ' ten', ' eleven', ' twelve', ' thirteen', ' fourteen', ' fifteen', ' sixteen', ' seventeen', ' eighteen', ' nineteen'); var tens = new Array('', '', ' twenty', ' thirty', ' forty', ' fifty', ' sixty', ' seventy', ' eighty', ' ninety'); var hundred = ' hundred'; var output = ''; var numString = num.toString(); if (num == 0) { return 'dontAddBigSufix'; } //the case of 10, 11, 12 ,13, .... 19 if (num < 20) { output = ones[num]; return output; } //100 and more if (numString.length == 3) { output = ones[parseInt(numString.charAt(0))] + hundred; output += tens[parseInt(numString.charAt(1))]; output += ones[parseInt(numString.charAt(2))]; return output; } output += tens[parseInt(numString.charAt(0))]; output += ones[parseInt(numString.charAt(1))]; return output; }
<input type="text" id="number" size="70" onkeyup="update();" /*this code prevent non numeric letters*/ onkeydown="return (event.ctrlKey || event.altKey || (47<event.keyCode && event.keyCode<58 && event.shiftKey==false) || (95<event.keyCode && event.keyCode<106) || (event.keyCode==8) || (event.keyCode==9) || (event.keyCode>34 && event.keyCode<40) || (event.keyCode==46) )"/> <br/> <div id="container">Here The Numbers Printed</div>
Advertisement
Answer
JavaScript is parsing the group of 3 numbers as an octal number when there’s a leading zero digit. When the group of three digits is all zeros, the result is the same whether the base is octal or decimal.
But when you give JavaScript ‘009’ (or ‘008’), that’s an invalid octal number, so you get zero back.
If you had gone through the whole set of numbers from 190,000,001 to 190,000,010 you’d hav seen JavaScript skip ‘…,008’ and ‘…,009’ but emit ‘eight’ for ‘…,010’. That’s the ‘Eureka!’ moment.
Change:
for (j = 0; j < finlOutPut.length; j++) { finlOutPut[j] = triConvert(parseInt(finlOutPut[j])); }
to
for (j = 0; j < finlOutPut.length; j++) { finlOutPut[j] = triConvert(parseInt(finlOutPut[j],10)); }
Code also kept on adding commas after every non-zero group, so I played with it and found the right spot to add the comma.
Old:
for (b = finlOutPut.length - 1; b >= 0; b--) { if (finlOutPut[b] != "dontAddBigSufix") { finlOutPut[b] = finlOutPut[b] + bigNumArry[bigScalCntr] + ' , '; bigScalCntr++; } else { //replace the string at finlOP[b] from "dontAddBigSufix" to empty String. finlOutPut[b] = ' '; bigScalCntr++; //advance the counter } } //convert The output Arry to , more printable string for(n = 0; n<finlOutPut.length; n++){ output +=finlOutPut[n]; }
New:
for (b = finlOutPut.length - 1; b >= 0; b--) { if (finlOutPut[b] != "dontAddBigSufix") { finlOutPut[b] = finlOutPut[b] + bigNumArry[bigScalCntr]; // <<< bigScalCntr++; } else { //replace the string at finlOP[b] from "dontAddBigSufix" to empty String. finlOutPut[b] = ' '; bigScalCntr++; //advance the counter } } //convert The output Arry to , more printable string var nonzero = false; // <<< for(n = 0; n<finlOutPut.length; n++){ if (finlOutPut[n] != ' ') { // <<< if (nonzero) output += ' , '; // <<< nonzero = true; // <<< } // <<< output +=finlOutPut[n]; }