Related
Leetcode problem:
You are given a string that represents time in the format hh:mm. Some of the digits are blank (represented by ?). Fill in ? such that the time represented by this string is the maximum possible. Maximum time: 23:59, minimum time: 00:00. You can assume that input string is always valid.
You can use the replace function ability of String.replace. The second parameter passed in is the position of the ?, so use that to look up the max value for that position in an array.
const maxValues = ["2", "3", ":", "5", "9"];
const maxTime = (time) => time.replace(/\?/g, (s, p, str) => {
if (p === 1 && str[0] !== '2' && str[0] !== '?' ) {
return '9';
}
return maxValues[p];
});
console.log(maxTime("?1:1?"))
console.log(maxTime("??:??"))
console.log(maxTime("11:11"))
console.log(maxTime("1?:?1"))
This is not a very elegant solution but it addresses the problem I pointed out in my reply to James, where the send H in HH can be either 9 or 3 depending on the time. This also is just different but also valid.
maxTime = (strTime) => {
let [...str] = strTime;
if (str[0] == "?") { str[0] = "2"; }
if (str[1] == "?" && str[0] < "2") { str[1] = "9"; } else { str[1] = "3"; }
if (str[3] == "?") { str[3] = "5"; }
if (str[4] == "?") { str[4] = "9"; }
return str.join('');
}
console.log(maxTime("?2:22")); // 22:22
console.log(maxTime("2?:22")); // 23:22
console.log(maxTime("22:?2")); // 22:52
console.log(maxTime("22:2?")); // 22:29
console.log(maxTime("0?:??")); // 09:59
console.log(maxTime("1?:??")); // 19:59
console.log(maxTime("??:??")); // 23:59
or a loop
const max = "29:59";
maxTime = (strTime) => {
let [...str] = strTime;
for (x = 0; x < 5; x++) { if (strTime[x] == "?") { str[x] = max[x]; }}
if (str[0] == "2" && strTime[1] == "?") { str[1] = "3"; }
return str.join('');
}
console.log(maxTime("?2:22")); // 22:22
console.log(maxTime("2?:22")); // 23:22
console.log(maxTime("22:?2")); // 22:52
console.log(maxTime("22:2?")); // 22:29
console.log(maxTime("0?:??")); // 09:59
console.log(maxTime("1?:??")); // 19:59
console.log(maxTime("??:??")); // 23:59
maxTime = (time) => {
const timeArr = time.split(":");
let hr = timeArr[0];
let mn = String(timeArr[1]);
if (mn.includes("?")) {
const mnArr = mn.split("");
if (mnArr[0] === "?" && mnArr[1] === "?") {
mn = "59";
} else if (mnArr[0] === "?") {
mn = "5" + mnArr[1];
} else if (mnArr[1] === "?") {
const temp = mnArr[0] === "5" ? "9" : "0";
mn = mnArr[0] + temp;
}
}
if (hr.includes("?")) {
const hrArr = hr.split("");
if (hrArr[0] === "?" && hrArr[1] === "?") {
hr = "23";
} else if (hrArr[0] === "?") {
hr = "2" + hrArr[1];
hr = Number(hr) <= 24 ? "1" + hrArr[1] : hr;
} else if (hrArr[1] === "?") {
const temp = hrArr[0] === "2" ? "3" : "9";
hr = hrArr[0] + temp;
}
}
return `(${time}) => ${hr}:${mn}`;
}
I'm writing some code that converts a given number into words, here's what I have got after googling. But I think it's a bit too long for such a simple task.
Two Regular Expressions and two for loops, I want something simpler.
I am trying to achieve this in as few lines of code as possible. here's what I've come up with so far:
Any suggestions?
var th = ['','thousand','million', 'billion','trillion'];
var dg = ['zero','one','two','three','four', 'five','six','seven','eight','nine'];
var tn = ['ten','eleven','twelve','thirteen', 'fourteen','fifteen','sixteen', 'seventeen','eighteen','nineteen'];
var tw = ['twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
function toWords(s) {
s = s.toString();
s = s.replace(/[\, ]/g,'');
if (s != parseFloat(s)) return 'not a number';
var x = s.indexOf('.');
if (x == -1)
x = s.length;
if (x > 15)
return 'too big';
var n = s.split('');
var str = '';
var sk = 0;
for (var i=0; i < x; i++) {
if ((x-i)%3==2) {
if (n[i] == '1') {
str += tn[Number(n[i+1])] + ' ';
i++;
sk=1;
} else if (n[i]!=0) {
str += tw[n[i]-2] + ' ';
sk=1;
}
} else if (n[i]!=0) { // 0235
str += dg[n[i]] +' ';
if ((x-i)%3==0) str += 'hundred ';
sk=1;
}
if ((x-i)%3==1) {
if (sk)
str += th[(x-i-1)/3] + ' ';
sk=0;
}
}
if (x != s.length) {
var y = s.length;
str += 'point ';
for (var i=x+1; i<y; i++)
str += dg[n[i]] +' ';
}
return str.replace(/\s+/g,' ');
}
Also, the above code converts to the English numbering system like Million/Billion, I need the South Asian numbering system, like in Lakhs and Crores.
Update: Looks like this is more useful than I thought. I've just published this on npm. https://www.npmjs.com/package/num-words
Here's a shorter code. with one RegEx and no loops. converts as you wanted, in south asian numbering system
var a = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
var b = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
function inWords (num) {
if ((num = num.toString()).length > 9) return 'overflow';
n = ('000000000' + num).substr(-9).match(/^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/);
if (!n) return; var str = '';
str += (n[1] != 0) ? (a[Number(n[1])] || b[n[1][0]] + ' ' + a[n[1][1]]) + 'crore ' : '';
str += (n[2] != 0) ? (a[Number(n[2])] || b[n[2][0]] + ' ' + a[n[2][1]]) + 'lakh ' : '';
str += (n[3] != 0) ? (a[Number(n[3])] || b[n[3][0]] + ' ' + a[n[3][1]]) + 'thousand ' : '';
str += (n[4] != 0) ? (a[Number(n[4])] || b[n[4][0]] + ' ' + a[n[4][1]]) + 'hundred ' : '';
str += (n[5] != 0) ? ((str != '') ? 'and ' : '') + (a[Number(n[5])] || b[n[5][0]] + ' ' + a[n[5][1]]) + 'only ' : '';
return str;
}
document.getElementById('number').onkeyup = function () {
document.getElementById('words').innerHTML = inWords(document.getElementById('number').value);
};
<span id="words"></span>
<input id="number" type="text" />
The only limitation is, you can convert maximum of 9 digits, which I think is more than sufficient in most cases..
"Deceptively simple task." – Potatoswatter
Indeed. There's many little devils hanging out in the details of this problem. It was very fun to solve tho.
EDIT: This update takes a much more compositional approach. Previously there was one big function which wrapped a couple other proprietary functions. Instead, this time we define generic reusable functions which could be used for many varieties of tasks. More about those after we take a look at numToWords itself …
// numToWords :: (Number a, String a) => a -> String
let numToWords = n => {
let a = [
'', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
];
let b = [
'', '', 'twenty', 'thirty', 'forty',
'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
];
let g = [
'', 'thousand', 'million', 'billion', 'trillion', 'quadrillion',
'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion'
];
// this part is really nasty still
// it might edit this again later to show how Monoids could fix this up
let makeGroup = ([ones,tens,huns]) => {
return [
num(huns) === 0 ? '' : a[huns] + ' hundred ',
num(ones) === 0 ? b[tens] : b[tens] && b[tens] + '-' || '',
a[tens+ones] || a[ones]
].join('');
};
// "thousands" constructor; no real good names for this, i guess
let thousand = (group,i) => group === '' ? group : `${group} ${g[i]}`;
// execute !
if (typeof n === 'number') return numToWords(String(n));
if (n === '0') return 'zero';
return comp (chunk(3)) (reverse) (arr(n))
.map(makeGroup)
.map(thousand)
.filter(comp(not)(isEmpty))
.reverse()
.join(' ');
};
Here are the dependencies:
You'll notice these require next to no documentation because their intents are immediately clear. chunk might be the only one that takes a moment to digest, but it's really not too bad. Plus the function name gives us a pretty good indication what it does, and it's probably a function we've encountered before.
const arr = x => Array.from(x);
const num = x => Number(x) || 0;
const str = x => String(x);
const isEmpty = xs => xs.length === 0;
const take = n => xs => xs.slice(0,n);
const drop = n => xs => xs.slice(n);
const reverse = xs => xs.slice(0).reverse();
const comp = f => g => x => f (g (x));
const not = x => !x;
const chunk = n => xs =>
isEmpty(xs) ? [] : [take(n)(xs), ...chunk (n) (drop (n) (xs))];
"So these make it better?"
Look at how the code has cleaned up significantly
// NEW CODE (truncated)
return comp (chunk(3)) (reverse) (arr(n))
.map(makeGroup)
.map(thousand)
.filter(comp(not)(isEmpty))
.reverse()
.join(' ');
// OLD CODE (truncated)
let grp = n => ('000' + n).substr(-3);
let rem = n => n.substr(0, n.length - 3);
let cons = xs => x => g => x ? [x, g && ' ' + g || '', ' ', xs].join('') : xs;
let iter = str => i => x => r => {
if (x === '000' && r.length === 0) return str;
return iter(cons(str)(fmt(x))(g[i]))
(i+1)
(grp(r))
(rem(r));
};
return iter('')(0)(grp(String(n)))(rem(String(n)));
Most importantly, the utility functions we added in the new code can be used other places in your app. This means that, as a side effect of implementing numToWords in this way, we get the other functions for free. Bonus soda !
Some tests
console.log(numToWords(11009));
//=> eleven thousand nine
console.log(numToWords(10000001));
//=> ten million one
console.log(numToWords(987));
//=> nine hundred eighty-seven
console.log(numToWords(1015));
//=> one thousand fifteen
console.log(numToWords(55111222333));
//=> fifty-five billion one hundred eleven million two hundred
// twenty-two thousand three hundred thirty-three
console.log(numToWords("999999999999999999999991"));
//=> nine hundred ninety-nine sextillion nine hundred ninety-nine
// quintillion nine hundred ninety-nine quadrillion nine hundred
// ninety-nine trillion nine hundred ninety-nine billion nine
// hundred ninety-nine million nine hundred ninety-nine thousand
// nine hundred ninety-one
console.log(numToWords(6000753512));
//=> six billion seven hundred fifty-three thousand five hundred
// twelve
Runnable demo
const arr = x => Array.from(x);
const num = x => Number(x) || 0;
const str = x => String(x);
const isEmpty = xs => xs.length === 0;
const take = n => xs => xs.slice(0,n);
const drop = n => xs => xs.slice(n);
const reverse = xs => xs.slice(0).reverse();
const comp = f => g => x => f (g (x));
const not = x => !x;
const chunk = n => xs =>
isEmpty(xs) ? [] : [take(n)(xs), ...chunk (n) (drop (n) (xs))];
// numToWords :: (Number a, String a) => a -> String
let numToWords = n => {
let a = [
'', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
];
let b = [
'', '', 'twenty', 'thirty', 'forty',
'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
];
let g = [
'', 'thousand', 'million', 'billion', 'trillion', 'quadrillion',
'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion'
];
// this part is really nasty still
// it might edit this again later to show how Monoids could fix this up
let makeGroup = ([ones,tens,huns]) => {
return [
num(huns) === 0 ? '' : a[huns] + ' hundred ',
num(ones) === 0 ? b[tens] : b[tens] && b[tens] + '-' || '',
a[tens+ones] || a[ones]
].join('');
};
let thousand = (group,i) => group === '' ? group : `${group} ${g[i]}`;
if (typeof n === 'number')
return numToWords(String(n));
else if (n === '0')
return 'zero';
else
return comp (chunk(3)) (reverse) (arr(n))
.map(makeGroup)
.map(thousand)
.filter(comp(not)(isEmpty))
.reverse()
.join(' ');
};
console.log(numToWords(11009));
//=> eleven thousand nine
console.log(numToWords(10000001));
//=> ten million one
console.log(numToWords(987));
//=> nine hundred eighty-seven
console.log(numToWords(1015));
//=> one thousand fifteen
console.log(numToWords(55111222333));
//=> fifty-five billion one hundred eleven million two hundred
// twenty-two thousand three hundred thirty-three
console.log(numToWords("999999999999999999999991"));
//=> nine hundred ninety-nine sextillion nine hundred ninety-nine
// quintillion nine hundred ninety-nine quadrillion nine hundred
// ninety-nine trillion nine hundred ninety-nine billion nine
// hundred ninety-nine million nine hundred ninety-nine thousand
// nine hundred ninety-one
console.log(numToWords(6000753512));
//=> six billion seven hundred fifty-three thousand five hundred
// twelve
You can transpile the code using babel.js if you want to see the ES5 variant
I spent a while developing a better solution to this. It can handle very big numbers but once they get over 16 digits you have pass the number in as a string. Something about the limit of JavaScript numbers.
function numberToEnglish( n ) {
var string = n.toString(), units, tens, scales, start, end, chunks, chunksLen, chunk, ints, i, word, words, and = 'and';
/* Remove spaces and commas */
string = string.replace(/[, ]/g,"");
/* Is number zero? */
if( parseInt( string ) === 0 ) {
return 'zero';
}
/* Array of units as words */
units = [ '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' ];
/* Array of tens as words */
tens = [ '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety' ];
/* Array of scales as words */
scales = [ '', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quatttuor-decillion', 'quindecillion', 'sexdecillion', 'septen-decillion', 'octodecillion', 'novemdecillion', 'vigintillion', 'centillion' ];
/* Split user argument into 3 digit chunks from right to left */
start = string.length;
chunks = [];
while( start > 0 ) {
end = start;
chunks.push( string.slice( ( start = Math.max( 0, start - 3 ) ), end ) );
}
/* Check if function has enough scale words to be able to stringify the user argument */
chunksLen = chunks.length;
if( chunksLen > scales.length ) {
return '';
}
/* Stringify each integer in each chunk */
words = [];
for( i = 0; i < chunksLen; i++ ) {
chunk = parseInt( chunks[i] );
if( chunk ) {
/* Split chunk into array of individual integers */
ints = chunks[i].split( '' ).reverse().map( parseFloat );
/* If tens integer is 1, i.e. 10, then add 10 to units integer */
if( ints[1] === 1 ) {
ints[0] += 10;
}
/* Add scale word if chunk is not zero and array item exists */
if( ( word = scales[i] ) ) {
words.push( word );
}
/* Add unit word if array item exists */
if( ( word = units[ ints[0] ] ) ) {
words.push( word );
}
/* Add tens word if array item exists */
if( ( word = tens[ ints[1] ] ) ) {
words.push( word );
}
/* Add 'and' string after units or tens integer if: */
if( ints[0] || ints[1] ) {
/* Chunk has a hundreds integer or chunk is the first of multiple chunks */
if( ints[2] || ! i && chunksLen ) {
words.push( and );
}
}
/* Add hundreds word if array item exists */
if( ( word = units[ ints[2] ] ) ) {
words.push( word + ' hundred' );
}
}
}
return words.reverse().join( ' ' );
}
// - - - - - Tests - - - - - -
function test(v) {
var sep = ('string'==typeof v)?'"':'';
console.log("numberToEnglish("+sep + v.toString() + sep+") = "+numberToEnglish(v));
}
test(2);
test(721);
test(13463);
test(1000001);
test("21,683,200,000,621,384");
You might want to try it recursive. It works for numbers between 0 and 999999. Keep in mind that (~~) does the same as Math.floor
var num = "zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen".split(" ");
var tens = "twenty thirty forty fifty sixty seventy eighty ninety".split(" ");
function number2words(n){
if (n < 20) return num[n];
var digit = n%10;
if (n < 100) return tens[~~(n/10)-2] + (digit? "-" + num[digit]: "");
if (n < 1000) return num[~~(n/100)] +" hundred" + (n%100 == 0? "": " " + number2words(n%100));
return number2words(~~(n/1000)) + " thousand" + (n%1000 != 0? " " + number2words(n%1000): "");
}
I like the result I got here which i think is easy to read and short enough to fit as a solution.
function NumInWords (number) {
const first = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
const tens = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
const mad = ['', 'thousand', 'million', 'billion', 'trillion'];
let word = '';
for (let i = 0; i < mad.length; i++) {
let tempNumber = number%(100*Math.pow(1000,i));
if (Math.floor(tempNumber/Math.pow(1000,i)) !== 0) {
if (Math.floor(tempNumber/Math.pow(1000,i)) < 20) {
word = first[Math.floor(tempNumber/Math.pow(1000,i))] + mad[i] + ' ' + word;
} else {
word = tens[Math.floor(tempNumber/(10*Math.pow(1000,i)))] + '-' + first[Math.floor(tempNumber/Math.pow(1000,i))%10] + mad[i] + ' ' + word;
}
}
tempNumber = number%(Math.pow(1000,i+1));
if (Math.floor(tempNumber/(100*Math.pow(1000,i))) !== 0) word = first[Math.floor(tempNumber/(100*Math.pow(1000,i)))] + 'hunderd ' + word;
}
return word;
}
console.log(NumInWords(89754697976431))
And the result is :
eighty-nine trillion seven hundred fifty-four billion six hundred ninety-seven million nine hundred seventy-six thousand four hundred thirty-one
<html>
<head>
<title>HTML - Convert numbers to words using JavaScript</title>
<script type="text/javascript">
function onlyNumbers(evt) {
var e = event || evt; // For trans-browser compatibility
var charCode = e.which || e.keyCode;
if (charCode > 31 && (charCode < 48 || charCode > 57))
return false;
return true;
}
function NumToWord(inputNumber, outputControl) {
var str = new String(inputNumber)
var splt = str.split("");
var rev = splt.reverse();
var once = ['Zero', ' One', ' Two', ' Three', ' Four', ' Five', ' Six', ' Seven', ' Eight', ' Nine'];
var twos = ['Ten', ' Eleven', ' Twelve', ' Thirteen', ' Fourteen', ' Fifteen', ' Sixteen', ' Seventeen', ' Eighteen', ' Nineteen'];
var tens = ['', 'Ten', ' Twenty', ' Thirty', ' Forty', ' Fifty', ' Sixty', ' Seventy', ' Eighty', ' Ninety'];
numLength = rev.length;
var word = new Array();
var j = 0;
for (i = 0; i < numLength; i++) {
switch (i) {
case 0:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = '' + once[rev[i]];
}
word[j] = word[j];
break;
case 1:
aboveTens();
break;
case 2:
if (rev[i] == 0) {
word[j] = '';
}
else if ((rev[i - 1] == 0) || (rev[i - 2] == 0)) {
word[j] = once[rev[i]] + " Hundred ";
}
else {
word[j] = once[rev[i]] + " Hundred and";
}
break;
case 3:
if (rev[i] == 0 || rev[i + 1] == 1) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if ((rev[i + 1] != 0) || (rev[i] > 0)) {
word[j] = word[j] + " Thousand";
}
break;
case 4:
aboveTens();
break;
case 5:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if (rev[i + 1] !== '0' || rev[i] > '0') {
word[j] = word[j] + " Lakh";
}
break;
case 6:
aboveTens();
break;
case 7:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if (rev[i + 1] !== '0' || rev[i] > '0') {
word[j] = word[j] + " Crore";
}
break;
case 8:
aboveTens();
break;
// This is optional.
// case 9:
// if ((rev[i] == 0) || (rev[i + 1] == 1)) {
// word[j] = '';
// }
// else {
// word[j] = once[rev[i]];
// }
// if (rev[i + 1] !== '0' || rev[i] > '0') {
// word[j] = word[j] + " Arab";
// }
// break;
// case 10:
// aboveTens();
// break;
default: break;
}
j++;
}
function aboveTens() {
if (rev[i] == 0) { word[j] = ''; }
else if (rev[i] == 1) { word[j] = twos[rev[i - 1]]; }
else { word[j] = tens[rev[i]]; }
}
word.reverse();
var finalOutput = '';
for (i = 0; i < numLength; i++) {
finalOutput = finalOutput + word[i];
}
document.getElementById(outputControl).innerHTML = finalOutput;
}
</script>
</head>
<body>
<h1>
HTML - Convert numbers to words using JavaScript</h1>
<input id="Text1" type="text" onkeypress="return onlyNumbers(this.value);" onkeyup="NumToWord(this.value,'divDisplayWords');"
maxlength="9" style="background-color: #efefef; border: 2px solid #CCCCC; font-size: large" />
<br />
<br />
<div id="divDisplayWords" style="font-size: 13; color: Teal; font-family: Arial;">
</div>
</body>
</html>
I modified MC Shaman's code to fix the bug of single number having and appear before it
function numberToEnglish( n ) {
var string = n.toString(), units, tens, scales, start, end, chunks, chunksLen, chunk, ints, i, word, words, and = 'and';
/* Remove spaces and commas */
string = string.replace(/[, ]/g,"");
/* Is number zero? */
if( parseInt( string ) === 0 ) {
return 'zero';
}
/* Array of units as words */
units = [ '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' ];
/* Array of tens as words */
tens = [ '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety' ];
/* Array of scales as words */
scales = [ '', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quatttuor-decillion', 'quindecillion', 'sexdecillion', 'septen-decillion', 'octodecillion', 'novemdecillion', 'vigintillion', 'centillion' ];
/* Split user argument into 3 digit chunks from right to left */
start = string.length;
chunks = [];
while( start > 0 ) {
end = start;
chunks.push( string.slice( ( start = Math.max( 0, start - 3 ) ), end ) );
}
/* Check if function has enough scale words to be able to stringify the user argument */
chunksLen = chunks.length;
if( chunksLen > scales.length ) {
return '';
}
/* Stringify each integer in each chunk */
words = [];
for( i = 0; i < chunksLen; i++ ) {
chunk = parseInt( chunks[i] );
if( chunk ) {
/* Split chunk into array of individual integers */
ints = chunks[i].split( '' ).reverse().map( parseFloat );
/* If tens integer is 1, i.e. 10, then add 10 to units integer */
if( ints[1] === 1 ) {
ints[0] += 10;
}
/* Add scale word if chunk is not zero and array item exists */
if( ( word = scales[i] ) ) {
words.push( word );
}
/* Add unit word if array item exists */
if( ( word = units[ ints[0] ] ) ) {
words.push( word );
}
/* Add tens word if array item exists */
if( ( word = tens[ ints[1] ] ) ) {
words.push( word );
}
/* Add 'and' string after units or tens integer if: */
if( ints[0] || ints[1] ) {
/* Chunk has a hundreds integer or chunk is the first of multiple chunks */
if( ints[2] || (i + 1) > chunksLen ) {
words.push( and );
}
}
/* Add hundreds word if array item exists */
if( ( word = units[ ints[2] ] ) ) {
words.push( word + ' hundred' );
}
}
}
return words.reverse().join( ' ' );
}
// - - - - - Tests - - - - - -
function figure(val) {
finalFig = numberToEnglish(val);
document.getElementById("words").innerHTML = finalFig;
}
<span id="words"></span>
<input id="number" type="text" onkeyup=figure(this.value) />
Update February 2021
Although this question is raised over 8 years ago with various solutions and answers, the easiest solution that can be easily updated to increase the scale by just inserting a name in the array without code modification; and also using very short code is the function below.
This solution is for the English reading of numbers (not the South-Asian System) and uses the standard US English (American way) of writing large numbers. i.e. it does not use the UK System (the UK system uses the word "and" like: "three hundred and twenty-two thousand").
Test cases are provided and also an input field.
Remember, it is "Unsigned Integers" that we are converting to words.
You can increase the scale[] array beyond Sextillion.
As the function is short, you can use it as an internal function in, say, currency conversion where decimal numbers are used and call it twice for the whole part and the fractional part.
Hope it is useful.
/********************************************************
* #function : integerToWords()
* #purpose : Converts Unsigned Integers to Words
* Using String Triplet Array.
* #version : 1.05
* #author : Mohsen Alyafei
* #date : 15 January 2021
* #param : {number} [integer numeric or string]
* #returns : {string} The wordified number string
********************************************************/
const 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","Hundred"],
Scale = ["","Thousand","Million","Billion","Trillion","Quadrillion","Quintillion","Sextillion"];
//==================================
const integerToWords = (n = 0) => {
if (n == 0) return "Zero"; // check for zero
n = ("0".repeat(2*(n+="").length % 3) + n).match(/.{3}/g); // create triplets array
if (n.length > Scale.length) return "Too Large"; // check if larger than scale array
let out= ""; return n.forEach((Triplet,pos) => { // loop into array for each triplet
if (+Triplet) { out+=' ' +(+Triplet[0] ? Ones[+Triplet[0]]+' '+ Tens[10] : "") +
' ' + (+Triplet.substr(1)< 20 ? Ones[+Triplet.substr(1)] :
Tens[+Triplet[1]] + (+Triplet[2] ? "-" : "") + Ones[+Triplet[2]]) +
' ' + Scale[n.length-pos-1]; }
}),out.replace(/\s+/g,' ').trim();}; // lazy job using trim()
//==================================
//=========================================
// Test Cases
//=========================================
var r=0; // test tracker
r |= test(0,"Zero");
r |= test(5,"Five");
r |= test(10,"Ten");
r |= test(19,"Nineteen");
r |= test(33,"Thirty-Three");
r |= test(100,"One Hundred");
r |= test(111,"One Hundred Eleven");
r |= test(890,"Eight Hundred Ninety");
r |= test(1234,"One Thousand Two Hundred Thirty-Four");
r |= test(12345,"Twelve Thousand Three Hundred Forty-Five");
r |= test(123456,"One Hundred Twenty-Three Thousand Four Hundred Fifty-Six");
r |= test(1234567,"One Million Two Hundred Thirty-Four Thousand Five Hundred Sixty-Seven");
r |= test(12345678,"Twelve Million Three Hundred Forty-Five Thousand Six Hundred Seventy-Eight");
r |= test(123456789,"One Hundred Twenty-Three Million Four Hundred Fifty-Six Thousand Seven Hundred Eighty-Nine");
r |= test(1234567890,"One Billion Two Hundred Thirty-Four Million Five Hundred Sixty-Seven Thousand Eight Hundred Ninety");
r |= test(1001,"One Thousand One");
r |= test(10001,"Ten Thousand One");
r |= test(100001,"One Hundred Thousand One");
r |= test(1000001,"One Million One");
r |= test(10000001,"Ten Million One");
r |= test(100000001,"One Hundred Million One");
r |= test(12012,"Twelve Thousand Twelve");
r |= test(120012,"One Hundred Twenty Thousand Twelve");
r |= test(1200012,"One Million Two Hundred Thousand Twelve");
r |= test(12000012,"Twelve Million Twelve");
r |= test(120000012,"One Hundred Twenty Million Twelve");
r |= test(75075,"Seventy-Five Thousand Seventy-Five");
r |= test(750075,"Seven Hundred Fifty Thousand Seventy-Five");
r |= test(7500075,"Seven Million Five Hundred Thousand Seventy-Five");
r |= test(75000075,"Seventy-Five Million Seventy-Five");
r |= test(750000075,"Seven Hundred Fifty Million Seventy-Five");
r |= test(1000,"One Thousand");
r |= test(1000000,"One Million");
r |= test(1000000000,"One Billion");
r |= test(1000000000000,"One Trillion");
r |= test("1000000000000000","One Quadrillion");
r |= test("1000000000000000000","One Quintillion");
r |= test("1000000100100100100","One Quintillion One Hundred Billion One Hundred Million One Hundred Thousand One Hundred");
if (r==0) console.log("All Tests Passed.");
//=====================================
// Tester Function
//=====================================
function test(n,should) {
let result = integerToWords(n);
if (result !== should) {console.log(`${n} Output : ${result}\n${n} Should be: ${should}`);return 1;}
}
<input type="text" name="number" placeholder="Please enter an Integer Number" onkeyup="word.innerHTML=integerToWords(this.value)" />
<div id="word"></div>
TypeScript Version Based on ES2022 + Fastest
Test on Typescript Playground
Hindi Version
class N2WHindi {
private static readonly zeroTo99: string[] =
'|एक|दो|तीन|चार|पाँच|छः|सात|आठ|नौ|दश|ग्यारह|बारह|तेरह|चौदह|पन्द्रह|सोलह|सत्रह|अठारह|उन्नीस|बीस|इक्कीस|बाईस|तेईस|चौबीस|पच्चीस|छब्बीस|सत्ताईस|अट्ठाईस|उनतीस|तीस|इकतीस|बत्तीस|तैंतीस|चौंतीस|पैंतीस|छत्तीस|सैंतीस|अड़तीस|उनतालीस|चालीस|इकतालीस|बयालीस|तैंतालीस|चौवालीस|पैंतालीस|छियालीस|सैंतालीस|अड़तालीस|उनचास|पचास|इक्यावन|बावन|तिरपन|चौवन|पचपन|छप्पन|सत्तावन|अट्ठावन|उनसठ|साठ|इकसठ|बासठ|तिरसठ|चौंसठ|पैंसठ|छियासठ|सड़सठ|अड़सठ|उनहत्तर|सत्तर|इकहत्तर|बहत्तर|तिहत्तर|चौहत्तर|पचहत्तर|छिहत्तर|सतहत्तर|अठहत्तर|उन्यासी|अस्सी|इक्यासी|बयासी|तिरासी|चौरासी|पचासी|छियासी|सत्तासी|अट्ठासी|नवासी|नब्बे|इक्यानबे|बानबे|तिरानबे|चौरानबे|पंचानबे|छियानबे|सत्तानबे|अट्ठानबे|निन्यान्बे'.split(
'|'
);
private static readonly place: string[] = 'हज़ार|लाख|करोड़|अरब|खरब|नील'.split('|');
public static convert(x: string): string {
let n: number = x.length;
x = n === 0 ? '00' : n === 1 || n % 2 === 0 ? '0' + x : x;
n = x.length;
let r: string = N2WHindi.zeroTo99[x.charCodeAt((n -= 2)) * 10 + x.charCodeAt(n + 1) - 528];
if (n > 0) {
const v: string = N2WHindi.zeroTo99[x.charCodeAt((n -= 1)) - 48];
if (v) r = v + ' सौ' + (r ? ' ' + r : '');
}
for (let i = 0; n > 0; i++) {
const v: string = N2WHindi.zeroTo99[x.charCodeAt((n -= 2)) * 10 + x.charCodeAt(n + 1) - 528];
if (v) r = v + ' ' + N2WHindi.place[i] + (r ? ' ' + r : '');
}
return r || 'शून्य';
}
}
Indian English Version
class N2WIndian {
private static readonly zeroTo99: string[] = [];
private static readonly place: string[] = 'Thousand|Lakh|Crore|Arab|Kharab|Nil'.split('|');
static {
const ones: string[] =
'|One|Two|Three|Four|Five|Six|Seven|Eight|Nine|Ten|Eleven|Twelve|Thirteen|Fourteen|Fifteen|Sixteen|Seventeen|Eighteen|Nineteen'.split(
'|'
);
const tens: string[] = '||Twenty|Thirty|Forty|Fifty|Sixty|Seventy|Eighty|Ninety'.split('|');
for (let i = 0; i < 100; i++) {
const t: number = Math.floor(i / 10);
const o: number = i % 10;
N2WIndian.zeroTo99.push(t < 2 ? ones[i] : tens[t] + (o ? ' ' + ones[o] : ''));
}
}
public static convert(x: string): string {
let n: number = x.length;
x = n === 0 ? '00' : n === 1 || n % 2 === 0 ? '0' + x : x;
n = x.length;
let r = N2WIndian.zeroTo99[x.charCodeAt((n -= 2)) * 10 + x.charCodeAt(n + 1) - 528];
if (n >= 1) {
const v: string = N2WIndian.zeroTo99[x.charCodeAt((n -= 1)) - 48];
if (v) r = v + ' Hundred' + (r ? ' ' + r : '');
}
for (let i = 0; n > 0; i++) {
const v: string = N2WIndian.zeroTo99[x.charCodeAt((n -= 2)) * 10 + x.charCodeAt(n + 1) - 528];
if (v) r = v + ' ' + N2WIndian.place[i] + (r ? ' ' + r : '');
}
return r || 'Zero';
}
}
International Version
class N2WIntl {
private static readonly zeroTo999: string[] = [];
private static readonly place =
'|Thousand|Million|Billion|Trillion|Quadrillion|Quintillion|Sextillion|Septillion|Octillion|Nonillion|Decillion|Undecillion|Duodecillion|Tredecillion|Quattuordecillion|Quindecillion|Sedecillion|Septendecillion|Octodecillion|Novendecillion|Vigintillion|Unvigintillion|Duovigintillion|Tresvigintillion|Quattuorvigintillion|Quinvigintillion|Sesvigintillion|Septemvigintillion|Octovigintillion|Novemvigintillion|Trigintillion|Untrigintillion|Duotrigintillion|Trestrigintillion|Quattuortrigintillion|Quintrigintillion|Sestrigintillion|Septentrigintillion|Octotrigintillion|Noventrigintillion|Quadragintillion'.split(
'|'
);
static {
const ones =
'|One|Two|Three|Four|Five|Six|Seven|Eight|Nine|Ten|Eleven|Twelve|Thirteen|Fourteen|Fifteen|Sixteen|Seventeen|Eighteen|Nineteen'.split(
'|'
);
const tens = '||Twenty|Thirty|Forty|Fifty|Sixty|Seventy|Eighty|Ninety'.split('|');
for (let i = 0; i < 100; i++) {
const t = Math.floor(i / 10);
const o = i % 10;
N2WIntl.zeroTo999[i] = t < 2 ? ones[i] : tens[t] + (o === 0 ? '' : ' ' + ones[o]);
}
for (let i = 100; i < 1000; i++) {
const h = Math.floor(i / 100);
const t = Math.floor(i / 10) % 10;
const o = i % 10;
const r = N2WIntl.zeroTo999[h] + ' Hundred';
N2WIntl.zeroTo999[i] = t === 0 && o === 0 ? r : r + ' ' + N2WIntl.zeroTo999[t * 10 + o];
}
}
public static convert(x: string): string {
let n = x.length;
x = n === 0 ? '000' : (n % 3 === 1 ? '00' : n % 3 === 2 ? '0' : '') + x;
n = x.length;
let r = '';
for (let i = 0; n > 0; i++) {
const v: string =
N2WIntl.zeroTo999[
x.charCodeAt((n -= 3)) * 100 + x.charCodeAt(n + 1) * 10 + x.charCodeAt(n + 2) - 5328
];
if (v) r = v + (i ? ' ' + N2WIntl.place[i] : '') + (r ? ' ' + r : '');
}
return r || 'Zero';
}
}
const test = () => {
{
let n = 5000000;
const test: string = '1234567890';
const t0 = performance.now();
while (n-- > 0) {
N2WHindi.convert(test);
}
const t1 = performance.now();
console.log('1234567890 to 5 Million times: ' + (t1 - t0) + 'ms');
console.log('10^15 -1 :\n' + '9'.repeat(15) + '\n' + N2WHindi.convert('9'.repeat(15)));
}
{
let n = 5000000;
const test: string = '1234567890';
const t0 = performance.now();
while (n-- > 0) {
N2WIndian.convert(test);
}
const t1 = performance.now();
console.log('1234567890 to 5 Million times: ' + (t1 - t0) + 'ms');
console.log('10^15 -1 :\n' + '9'.repeat(15) + '\n' + N2WIndian.convert('9'.repeat(15)));
}
{
let n = 5000000;
const test: string = '1234567890';
const t0 = performance.now();
while (n-- > 0) {
N2WIntl.convert(test);
}
const t1 = performance.now();
console.log('1234567890 to 5 Million times: ' + (t1 - t0) + 'ms');
console.log('10^126 -1 :\n' + '9'.repeat(126) + '\n' + N2WIntl.convert('9'.repeat(126)));
}
};
test();
Example
N2WHindi.convert('122356')
'एक लाख बाईस हज़ार तीन सौ छप्पन'
N2WIndian.convert('122356')
'One Lakh Twenty Two Thousand Three Hundred Fifty Six'
N2WIntl.convert('122356')
'One Hundred Twenty Two Thousand Three Hundred Fifty Six'
Example to convert currency
const [r, p] = "23.54".split('.');
`${N2WHindi.convert(r)} रुपया और ${N2WHindi.convert(p)} पैसा`
'तेईस रुपया और चौवन पैसा'
`${N2WIndian.convert(r)} Rupees and ${N2WIndian.convert(p)} Paisa`
'Twenty Three Rupees and Fifty Four Paisa'
`${N2WIntl.convert(r)} Dollars and ${N2WIntl.convert(p)} Cents`
'Twenty Three Dollars and Fifty Four Cents'
Converting the input string into a number rather than keeping it as a string, limits the solution to the maximum allowed float / integer value on that machine/browser. My script below handles currency up to 1 Trillion dollars - 1 cent :-). I can be extended to handle up to 999 Trillions by adding 3 or 4 lines of code.
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"];
function words999(n999) { // n999 is an integer less than or equal to 999.
//
// Accept any 3 digit int incl 000 & 999 and return words.
//
var words = ''; var Hn = 0; var n99 = 0;
Hn = Math.floor(n999 / 100); // # of hundreds in it
if (Hn > 0) { // if at least one 100
words = words99(Hn) + " Hundred"; // one call for hundreds
}
n99 = n999 - (Hn * 100); // subtract the hundreds.
words += ((words == '')?'':' ') + words99(n99); // combine the hundreds with tens & ones.
return words;
} // function words999( n999 )
function words99(n99) { // n99 is an integer less than or equal to 99.
//
// Accept any 2 digit int incl 00 & 99 and return words.
//
var words = ''; var Dn = 0; var Un = 0;
Dn = Math.floor(n99 / 10); // # of tens
Un = n99 % 10; // units
if (Dn > 0 || Un > 0) {
if (Dn < 2) {
words += ones[Dn * 10 + Un]; // words for a # < 20
} else {
words += tens[Dn];
if (Un > 0) words += "-" + ones[Un];
}
} // if ( Dn > 0 || Un > 0 )
return words;
} // function words99( n99 )
function getAmtInWords(id1, id2) { // use numeric value of id1 to populate text in id2
//
// Read numeric amount field and convert into word amount
//
var t1 = document.getElementById(id1).value;
var t2 = t1.trim();
amtStr = t2.replace(/,/g,''); // $123,456,789.12 = 123456789.12
dotPos = amtStr.indexOf('.'); // position of dot before cents, -ve if it doesn't exist.
if (dotPos > 0) {
dollars = amtStr.slice(0,dotPos); // 1234.56 = 1234
cents = amtStr.slice(dotPos+1); // 1234.56 = .56
} else if (dotPos == 0) {
dollars = '0';
cents = amtStr.slice(dotPos+1); // 1234.56 = .56
} else {
dollars = amtStr.slice(0); // 1234 = 1234
cents = '0';
}
t1 = '000000000000' + dollars; // to extend to trillion, use 15 zeros
dollars = t1.slice(-12); // and -15 here.
billions = Number(dollars.substr(0,3));
millions = Number(dollars.substr(3,3));
thousands = Number(dollars.substr(6,3));
hundreds = Number(dollars.substr(9,3));
t1 = words999(billions); bW = t1.trim(); // Billions in words
t1 = words999(millions); mW = t1.trim(); // Millions in words
t1 = words999(thousands); tW = t1.trim(); // Thousands in words
t1 = words999(hundreds); hW = t1.trim(); // Hundreds in words
t1 = words99(cents); cW = t1.trim(); // Cents in words
var totAmt = '';
if (bW != '') totAmt += ((totAmt != '') ? ' ' : '') + bW + ' Billion';
if (mW != '') totAmt += ((totAmt != '') ? ' ' : '') + mW + ' Million';
if (tW != '') totAmt += ((totAmt != '') ? ' ' : '') + tW + ' Thousand';
if (hW != '') totAmt += ((totAmt != '') ? ' ' : '') + hW + ' Dollars';
if (cW != '') totAmt += ((totAmt != '') ? ' and ' : '') + cW + ' Cents';
// alert('totAmt = ' + totAmt); // display words in a alert
t1 = document.getElementById(id2).value;
t2 = t1.trim();
if (t2 == '') document.getElementById(id2).value = totAmt;
return false;
} // function getAmtInWords( id1, id2 )
// ======================== [ End Code ] ====================================
If you need with Cent then you may use this one
<script>
var iWords = ['zero', ' one', ' two', ' three', ' four', ' five', ' six', ' seven', ' eight', ' nine'];
var ePlace = ['ten', ' eleven', ' twelve', ' thirteen', ' fourteen', ' fifteen', ' sixteen', ' seventeen', ' eighteen', ' nineteen'];
var tensPlace = ['', ' ten', ' twenty', ' thirty', ' forty', ' fifty', ' sixty', ' seventy', ' eighty', ' ninety'];
var inWords = [];
var numReversed, inWords, actnumber, i, j;
function tensComplication() {
if (actnumber[i] == 0) {
inWords[j] = '';
} else if (actnumber[i] == 1) {
inWords[j] = ePlace[actnumber[i - 1]];
} else {
inWords[j] = tensPlace[actnumber[i]];
}
}
function convertAmount() {
var numericValue = document.getElementById('bdt').value;
numericValue = parseFloat(numericValue).toFixed(2);
var amount = numericValue.toString().split('.');
var taka = amount[0];
var paisa = amount[1];
document.getElementById('container').innerHTML = convert(taka) +" taka and "+ convert(paisa)+" paisa only";
}
function convert(numericValue) {
inWords = []
if(numericValue == "00" || numericValue =="0"){
return 'zero';
}
var obStr = numericValue.toString();
numReversed = obStr.split('');
actnumber = numReversed.reverse();
if (Number(numericValue) == 0) {
document.getElementById('container').innerHTML = 'BDT Zero';
return false;
}
var iWordsLength = numReversed.length;
var finalWord = '';
j = 0;
for (i = 0; i < iWordsLength; i++) {
switch (i) {
case 0:
if (actnumber[i] == '0' || actnumber[i + 1] == '1') {
inWords[j] = '';
} else {
inWords[j] = iWords[actnumber[i]];
}
inWords[j] = inWords[j] + '';
break;
case 1:
tensComplication();
break;
case 2:
if (actnumber[i] == '0') {
inWords[j] = '';
} else if (actnumber[i - 1] !== '0' && actnumber[i - 2] !== '0') {
inWords[j] = iWords[actnumber[i]] + ' hundred';
} else {
inWords[j] = iWords[actnumber[i]] + ' hundred';
}
break;
case 3:
if (actnumber[i] == '0' || actnumber[i + 1] == '1') {
inWords[j] = '';
} else {
inWords[j] = iWords[actnumber[i]];
}
if (actnumber[i + 1] !== '0' || actnumber[i] > '0') {
inWords[j] = inWords[j] + ' thousand';
}
break;
case 4:
tensComplication();
break;
case 5:
if (actnumber[i] == '0' || actnumber[i + 1] == '1') {
inWords[j] = '';
} else {
inWords[j] = iWords[actnumber[i]];
}
if (actnumber[i + 1] !== '0' || actnumber[i] > '0') {
inWords[j] = inWords[j] + ' lakh';
}
break;
case 6:
tensComplication();
break;
case 7:
if (actnumber[i] == '0' || actnumber[i + 1] == '1') {
inWords[j] = '';
} else {
inWords[j] = iWords[actnumber[i]];
}
inWords[j] = inWords[j] + ' crore';
break;
case 8:
tensComplication();
break;
default:
break;
}
j++;
}
inWords.reverse();
for (i = 0; i < inWords.length; i++) {
finalWord += inWords[i];
}
return finalWord;
}
</script>
<input type="text" name="bdt" id="bdt" />
<input type="button" name="sr1" value="Click Here" onClick="convertAmount()"/>
<div id="container"></div>
js fiddle
Here taka mean USD and paisa mean cent
This is in response to #LordZardeck's comment to #naomik's excellent answer above. Sorry, I would've commented directly but I've never posted before so I don't have the privilege to do so, so I am posting here instead.
Anyhow, I just happened to translate the ES5 version to a more readable form this past weekend so I'm sharing it here. This should be faithful to the original (including the recent edit) and I hope the naming is clear and accurate.
function int_to_words(int) {
if (int === 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','fourty','fifty','sixty','seventy','eighty','ninety'];
var SCALE = ['','thousand','million','billion','trillion','quadrillion','quintillion','sextillion','septillion','octillion','nonillion'];
// Return string of first three digits, padded with zeros if needed
function get_first(str) {
return ('000' + str).substr(-3);
}
// Return string of digits with first three digits chopped off
function get_rest(str) {
return str.substr(0, str.length - 3);
}
// Return string of triplet convereted to words
function triplet_to_words(_3rd, _2nd, _1st) {
return (_3rd == '0' ? '' : ONES[_3rd] + ' hundred ') + (_1st == '0' ? TENS[_2nd] : TENS[_2nd] && TENS[_2nd] + '-' || '') + (ONES[_2nd + _1st] || ONES[_1st]);
}
// Add to words, triplet words with scale word
function add_to_words(words, triplet_words, scale_word) {
return triplet_words ? triplet_words + (scale_word && ' ' + scale_word || '') + ' ' + words : words;
}
function iter(words, i, first, rest) {
if (first == '000' && rest.length === 0) return words;
return iter(add_to_words(words, triplet_to_words(first[0], first[1], first[2]), SCALE[i]), ++i, get_first(rest), get_rest(rest));
}
return iter('', 0, get_first(String(int)), get_rest(String(int)));
}
var inWords = function(totalRent){
//console.log(totalRent);
var a = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
var b = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
var number = parseFloat(totalRent).toFixed(2).split(".");
var num = parseInt(number[0]);
var digit = parseInt(number[1]);
//console.log(num);
if ((num.toString()).length > 9) return 'overflow';
var n = ('000000000' + num).substr(-9).match(/^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/);
var d = ('00' + digit).substr(-2).match(/^(\d{2})$/);;
if (!n) return; var str = '';
str += (n[1] != 0) ? (a[Number(n[1])] || b[n[1][0]] + ' ' + a[n[1][1]]) + 'crore ' : '';
str += (n[2] != 0) ? (a[Number(n[2])] || b[n[2][0]] + ' ' + a[n[2][1]]) + 'lakh ' : '';
str += (n[3] != 0) ? (a[Number(n[3])] || b[n[3][0]] + ' ' + a[n[3][1]]) + 'thousand ' : '';
str += (n[4] != 0) ? (a[Number(n[4])] || b[n[4][0]] + ' ' + a[n[4][1]]) + 'hundred ' : '';
str += (n[5] != 0) ? (a[Number(n[5])] || b[n[5][0]] + ' ' + a[n[5][1]]) + 'Rupee ' : '';
str += (d[1] != 0) ? ((str != '' ) ? "and " : '') + (a[Number(d[1])] || b[d[1][0]] + ' ' + a[d[1][1]]) + 'Paise ' : 'Only!';
console.log(str);
return str;
}
This is modified code supports for Indian Rupee with 2 decimal place.
Below are the translations from
integer to word
float to word
money to word
Test cases are at the bottom
var ONE_THOUSAND = Math.pow(10, 3);
var ONE_MILLION = Math.pow(10, 6);
var ONE_BILLION = Math.pow(10, 9);
var ONE_TRILLION = Math.pow(10, 12);
var ONE_QUADRILLION = Math.pow(10, 15);
var ONE_QUINTILLION = Math.pow(10, 18);
function integerToWord(integer) {
var prefix = '';
var suffix = '';
if (!integer){ return "zero"; }
if(integer < 0){
prefix = "negative";
suffix = integerToWord(-1 * integer);
return prefix + " " + suffix;
}
if(integer <= 90){
switch (integer) {
case integer < 0:
prefix = "negative";
suffix = integerToWord(-1 * integer);
return prefix + " " + suffix;
case 1: return "one";
case 2: return "two";
case 3: return "three";
case 4: return "four";
case 5: return "five";
case 6: return "six";
case 7: return "seven";
case 8: return "eight";
case 9: return "nine";
case 10: return "ten";
case 11: return "eleven";
case 12: return "twelve";
case 13: return "thirteen";
case 14: return "fourteen";
case 15: return "fifteen";
case 16: return "sixteen";
case 17: return "seventeen";
case 18: return "eighteen";
case 19: return "nineteen";
case 20: return "twenty";
case 30: return "thirty";
case 40: return "forty";
case 50: return "fifty";
case 60: return "sixty";
case 70: return "seventy";
case 80: return "eighty";
case 90: return "ninety";
default: break;
}
}
if(integer < 100){
prefix = integerToWord(integer - integer % 10);
suffix = integerToWord(integer % 10);
return prefix + "-" + suffix;
}
if(integer < ONE_THOUSAND){
prefix = integerToWord(parseInt(Math.floor(integer / 100), 10) ) + " hundred";
if (integer % 100){ suffix = " and " + integerToWord(integer % 100); }
return prefix + suffix;
}
if(integer < ONE_MILLION){
prefix = integerToWord(parseInt(Math.floor(integer / ONE_THOUSAND), 10)) + " thousand";
if (integer % ONE_THOUSAND){ suffix = integerToWord(integer % ONE_THOUSAND); }
}
else if(integer < ONE_BILLION){
prefix = integerToWord(parseInt(Math.floor(integer / ONE_MILLION), 10)) + " million";
if (integer % ONE_MILLION){ suffix = integerToWord(integer % ONE_MILLION); }
}
else if(integer < ONE_TRILLION){
prefix = integerToWord(parseInt(Math.floor(integer / ONE_BILLION), 10)) + " billion";
if (integer % ONE_BILLION){ suffix = integerToWord(integer % ONE_BILLION); }
}
else if(integer < ONE_QUADRILLION){
prefix = integerToWord(parseInt(Math.floor(integer / ONE_TRILLION), 10)) + " trillion";
if (integer % ONE_TRILLION){ suffix = integerToWord(integer % ONE_TRILLION); }
}
else if(integer < ONE_QUINTILLION){
prefix = integerToWord(parseInt(Math.floor(integer / ONE_QUADRILLION), 10)) + " quadrillion";
if (integer % ONE_QUADRILLION){ suffix = integerToWord(integer % ONE_QUADRILLION); }
} else {
return '';
}
return prefix + " " + suffix;
}
function moneyToWord(value){
var decimalValue = (value % 1);
var integer = value - decimalValue;
decimalValue = Math.round(decimalValue * 100);
var decimalText = !decimalValue? '': integerToWord(decimalValue) + ' cent' + (decimalValue === 1? '': 's');
var integerText= !integer? '': integerToWord(integer) + ' dollar' + (integer === 1? '': 's');
return (
integer && !decimalValue? integerText:
integer && decimalValue? integerText + ' and ' + decimalText:
!integer && decimalValue? decimalText:
'zero cents'
);
}
function floatToWord(value){
var decimalValue = (value % 1);
var integer = value - decimalValue;
decimalValue = Math.round(decimalValue * 100);
var decimalText = !decimalValue? '':
decimalValue < 10? "point o' " + integerToWord(decimalValue):
decimalValue % 10 === 0? 'point ' + integerToWord(decimalValue / 10):
'point ' + integerToWord(decimalValue);
return (
integer && !decimalValue? integerToWord(integer):
integer && decimalValue? [integerToWord(integer), decimalText].join(' '):
!integer && decimalValue? decimalText:
integerToWord(0)
);
}
// test
(function(){
console.log('integerToWord ==================================');
for(var i = 0; i < 101; ++i){
console.log('%s=%s', i, integerToWord(i));
}
console.log('floatToWord ====================================');
i = 131;
while(i--){
console.log('%s=%s', i / 100, floatToWord(i / 100));
}
console.log('moneyToWord ====================================');
for(i = 0; i < 131; ++i){
console.log('%s=%s', i / 100, moneyToWord(i / 100));
}
}());
Another conversion that uses remainders and supports different languages:
function numberToWords(number) {
var result = [];
var fraction = number.toFixed(2).split('.');
var integer_part = parseInt(fraction[0]);
// var fractional_part = parseInt(fraction[1]); -- not handled here
var previousNumber = null;
for (var i = 0; i < fraction[0].length; i++) {
var reminder = Math.floor(integer_part % 10);
integer_part /= 10;
var name = getNumberName(reminder, i, fraction[0].length, previousNumber);
previousNumber = reminder;
if (name)
result.push(name);
}
result.reverse();
return result.join(' ');
}
The getNumberName function is language-dependent and handles numbers up to 9999 (but it is easy to extend it to handle larger numbers):
function getNumberName(number, power, places, previousNumber) {
var result = "";
if (power == 1) {
result = handleTeensAndTys(number, previousNumber);
} else if (power == 0 && places != 1 || number == 0) {
// skip number that was handled in teens and zero
} else {
result = locale.numberNames[number.toString()] + locale.powerNames[power.toString()];
}
return result;
}
handleTeensAndTys handles multiples of ten:
function handleTeensAndTys(number, previousNumber) {
var result = "";
if (number == 1) { // teens
if (previousNumber in locale.specialTeenNames) {
result = locale.specialTeenNames[previousNumber];
} else if (previousNumber in locale.specialTyNames) {
result = locale.specialTyNames[previousNumber] + locale.teenSuffix;
} else {
result = locale.numberNames[previousNumber] + locale.teenSuffix;
}
} else if (number == 0) { // previousNumber was not handled in teens
result = locale.numberNames[previousNumber.toString()];
} else { // other tys
if (number in locale.specialTyNames) {
result = locale.specialTyNames[number];
} else {
result = locale.numberNames[number];
}
result += locale.powerNames[1];
if (previousNumber != 0) {
result += " " + locale.numberNames[previousNumber.toString()];
}
}
return result;
}
Finally, locale examples:
var locale = { // English
numberNames: {1: "one", 2: "two", 3: "three", 4: "four", 5: "five", 6: "six", 7: "seven", 8: "eight", 9: "nine" },
powerNames: {0: "", 1: "ty", 2: " hundred", 3: " thousand" },
specialTeenNames: {0: "ten", 1: "eleven", 2: "twelve" },
specialTyNames: {2: "twen", 3: "thir", 5: "fif" },
teenSuffix: "teen"
};
var locale = { // Estonian
numberNames: {1: "üks", 2: "kaks", 3: "kolm", 4: "neli", 5: "viis", 6: "kuus", 7: "seitse", 8: "kaheksa", 9: "üheksa"},
powerNames: {0: "", 1: "kümmend", 2: "sada", 3: " tuhat" },
specialTeenNames: {0: "kümme"},
specialTyNames: {},
teenSuffix: "teist"
};
Here's a JSFiddle with tests: https://jsfiddle.net/rcrxna7v/15/
Function that will work with decimal values also
function amountToWords(amountInDigits){
// American Numbering System
var th = ['','thousand','million', 'billion','trillion'];
var dg = ['zero','one','two','three','four', 'five','six','seven','eight','nine'];
var tn = ['ten','eleven','twelve','thirteen', 'fourteen','fifteen','sixteen', 'seventeen','eighteen','nineteen'];
var tw = ['twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
function toWords(s){
s = s.toString();
s = s.replace(/[\, ]/g,'');
if (s != parseFloat(s))
return 'not a number';
var x = s.indexOf('.');
if (x == -1) x = s.length;
if (x > 15) return 'too big';
var n = s.split('');
var str = '';
var sk = 0;
for (var i=0; i < x; i++){
if ((x-i)%3==2){
if (n[i] == '1') {
str += tn[Number(n[i+1])] + ' ';
i++; sk=1;
} else if (n[i]!=0) {
str += tw[n[i]-2] + ' ';sk=1;
}
} else if (n[i]!=0) {
str += dg[n[i]] +' ';
if ((x-i)%3==0)
str += 'hundred ';
sk=1;
} if ((x-i)%3==1) {
if (sk) str += th[(x-i-1)/3] + ' ';sk=0;
}
}
if (x != s.length) {
var y = s.length;
str += 'point ';
for (var i=x+1; i<y; i++) str += dg[n[i]] +' ';
}
return str.replace(/\s+/g,' ');
}
return toWords(amountInDigits);
}
<input type="text" name="number" placeholder="Number OR Amount" onkeyup="word.innerHTML=amountToWords(this.value)" />
<div id="word"></div>
I modified #McShaman's code, converted it to CoffeeScript, and added docs via JSNice. Here's the result, for those interested (English):
###
Convert an integer to an English string equivalent
#param {Integer} number the integer to be converted
#return {String} the English number equivalent
###
inWords = (number) ->
###
#property {Array}
###
englishIntegers = [
""
"one "
"two "
"three "
"four "
"five "
"six "
"seven "
"eight "
"nine "
"ten "
"eleven "
"twelve "
"thirteen "
"fourteen "
"fifteen "
"sixteen "
"seventeen "
"eighteen "
"nineteen "
]
###
#property {Array}
###
englishIntegerTens = [
""
""
"twenty"
"thirty"
"forty"
"fifty"
"sixty"
"seventy"
"eighty"
"ninety"
]
###
#property {Array}
###
englishIntegerThousands = [
"thousand"
"million"
""
]
number = number.toString()
return "" if number.length > 9
###
#property {string}
###
number = ("000000000" + number).substr(-9)
###
#property {(Array.<string>|null)}
###
number = number.match(/.{3}/g)
###
#property {string}
###
convertedWords = ""
###
#property {number}
###
i = 0
while i < englishIntegerThousands.length
###
#property {string}
###
currentNumber = number[i]
###
#property {string}
###
tempResult = ""
tempResult += (if convertedWords isnt "" then " " + englishIntegerThousands[i] + " " else "")
tempResult += (if currentNumber[0] isnt 0 then englishIntegers[Number(currentNumber[0])] + "hundred " else "")
###
#property {string}
###
currentNumber = currentNumber.substr(1)
tempResult += (if currentNumber isnt 0 then ((if tempResult isnt "" then "and " else "")) + (englishIntegers[Number(currentNumber)] or englishIntegerTens[currentNumber[0]] + " " + englishIntegers[currentNumber[1]]) else "")
convertedWords += tempResult
i++
convertedWords
Though, this question has been answered - still I want to share something I recently developed in java script (based on the logic of an old C#. Net implementation I found in Internet) for converting Indian currency values to Words. It can handle up to 40 digits. You can have a look.
Usage:
InrToWordConverter.Initialize();.
var inWords = InrToWordConverter.ConvertToWord(amount);
Implementation:
htPunctuation = {};
listStaticSuffix = {};
listStaticPrefix = {};
listHelpNotation = {};
var InrToWordConverter = function () {
};
InrToWordConverter.Initialize = function () {
InrToWordConverter.LoadStaticPrefix();
InrToWordConverter.LoadStaticSuffix();
InrToWordConverter.LoadHelpofNotation();
};
InrToWordConverter.ConvertToWord = function (value) {
value = value.toString();
if (value) {
var tokens = value.split(".");
var rsPart = "";
var psPart = "";
if (tokens.length === 2) {
rsPart = String.trim(tokens[0]) || "0";
psPart = String.trim(tokens[1]) || "0";
}
else if (tokens.length === 1) {
rsPart = String.trim(tokens[0]) || "0";
psPart = "0";
}
else {
rsPart = "0";
psPart = "0";
}
htPunctuation = {};
var rsInWords = InrToWordConverter.ConvertToWordInternal(rsPart) || "Zero";
var psInWords = InrToWordConverter.ConvertToWordInternal(psPart) || "Zero";
var result = "Rupees " + rsInWords + "and " + psInWords + " Paise.";
return result;
}
};
InrToWordConverter.ConvertToWordInternal = function (value) {
var convertedString = "";
if (!(value.toString().length > 40))
{
if (InrToWordConverter.IsNumeric(value.toString()))
{
try
{
var strValue = InrToWordConverter.Reverse(value);
switch (strValue.length)
{
case 1:
if (parseInt(strValue.toString()) > 0) {
convertedString = InrToWordConverter.GetWordConversion(value);
}
else {
convertedString = "Zero ";
}
break;
case 2:
convertedString = InrToWordConverter.GetWordConversion(value);
break;
default:
InrToWordConverter.InsertToPunctuationTable(strValue);
InrToWordConverter.ReverseHashTable();
convertedString = InrToWordConverter.ReturnHashtableValue();
break;
}
}
catch (exception) {
convertedString = "Unexpected Error Occured <br/>";
}
}
else {
convertedString = "Please Enter Numbers Only, Decimal Values Are not supported";
}
}
else {
convertedString = "Please Enter Value in Less Then or Equal to 40 Digit";
}
return convertedString;
};
InrToWordConverter.IsNumeric = function (valueInNumeric) {
var isFine = true;
valueInNumeric = valueInNumeric || "";
var len = valueInNumeric.length;
for (var i = 0; i < len; i++) {
var ch = valueInNumeric[i];
if (!(ch >= '0' && ch <= '9')) {
isFine = false;
break;
}
}
return isFine;
};
InrToWordConverter.ReturnHashtableValue = function () {
var strFinalString = "";
var keysArr = [];
for (var key in htPunctuation) {
keysArr.push(key);
}
for (var i = keysArr.length - 1; i >= 0; i--) {
var hKey = keysArr[i];
if (InrToWordConverter.GetWordConversion((htPunctuation[hKey]).toString()) !== "") {
strFinalString = strFinalString + InrToWordConverter.GetWordConversion((htPunctuation[hKey]).toString()) + InrToWordConverter.StaticPrefixFind((hKey).toString());
}
}
return strFinalString;
};
InrToWordConverter.ReverseHashTable = function () {
var htTemp = {};
for (var key in htPunctuation) {
var item = htPunctuation[key];
htTemp[key] = InrToWordConverter.Reverse(item.toString());
}
htPunctuation = {};
htPunctuation = htTemp;
};
InrToWordConverter.InsertToPunctuationTable = function (strValue) {
htPunctuation[1] = strValue.substr(0, 3).toString();
var j = 2;
for (var i = 3; i < strValue.length; i = i + 2) {
if (strValue.substr(i).length > 0) {
if (strValue.substr(i).length >= 2) {
htPunctuation[j] = strValue.substr(i, 2).toString();
}
else {
htPunctuation[j] = strValue.substr(i, 1).toString();
}
}
else {
break;
}
j++;
}
};
InrToWordConverter.Reverse = function (strValue) {
var reversed = "";
for (var i in strValue) {
var ch = strValue[i];
reversed = ch + reversed;
}
return reversed;
};
InrToWordConverter.GetWordConversion = function (inputNumber) {
var toReturnWord = "";
if (inputNumber.length <= 3 && inputNumber.length > 0) {
if (inputNumber.length === 3) {
if (parseInt(inputNumber.substr(0, 1)) > 0) {
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(0, 1)) + "Hundred ";
}
var tempString = InrToWordConverter.StaticSuffixFind(inputNumber.substr(1, 2));
if (tempString === "")
{
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(1, 1) + "0");
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(2, 1));
}
toReturnWord = toReturnWord + tempString;
}
if (inputNumber.length === 2)
{
var tempString = InrToWordConverter.StaticSuffixFind(inputNumber.substr(0, 2));
if (tempString === "")
{
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(0, 1) + "0");
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(1, 1));
}
toReturnWord = toReturnWord + tempString;
}
if (inputNumber.length === 1)
{
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(0, 1));
}
}
return toReturnWord;
};
InrToWordConverter.StaticSuffixFind = function (numberKey) {
var valueFromNumber = "";
for (var key in listStaticSuffix) {
if (String.trim(key.toString()) === String.trim(numberKey)) {
valueFromNumber = listStaticSuffix[key].toString();
break;
}
}
return valueFromNumber;
};
InrToWordConverter.StaticPrefixFind = function (numberKey) {
var valueFromNumber = "";
for (var key in listStaticPrefix) {
if (String.trim(key) === String.trim(numberKey)) {
valueFromNumber = listStaticPrefix[key].toString();
break;
}
}
return valueFromNumber;
};
InrToWordConverter.StaticHelpNotationFind = function (numberKey) {
var helpText = "";
for (var key in listHelpNotation) {
if (String.trim(key.toString()) === String.trim(numberKey)) {
helpText = listHelpNotation[key].toString();
break;
}
}
return helpText;
};
InrToWordConverter.LoadStaticPrefix = function () {
listStaticPrefix[2] = "Thousand ";
listStaticPrefix[3] = "Lac ";
listStaticPrefix[4] = "Crore ";
listStaticPrefix[5] = "Arab ";
listStaticPrefix[6] = "Kharab ";
listStaticPrefix[7] = "Neel ";
listStaticPrefix[8] = "Padma ";
listStaticPrefix[9] = "Shankh ";
listStaticPrefix[10] = "Maha-shankh ";
listStaticPrefix[11] = "Ank ";
listStaticPrefix[12] = "Jald ";
listStaticPrefix[13] = "Madh ";
listStaticPrefix[14] = "Paraardha ";
listStaticPrefix[15] = "Ant ";
listStaticPrefix[16] = "Maha-ant ";
listStaticPrefix[17] = "Shisht ";
listStaticPrefix[18] = "Singhar ";
listStaticPrefix[19] = "Maha-singhar ";
listStaticPrefix[20] = "Adant-singhar ";
};
InrToWordConverter.LoadStaticSuffix = function () {
listStaticSuffix[1] = "One ";
listStaticSuffix[2] = "Two ";
listStaticSuffix[3] = "Three ";
listStaticSuffix[4] = "Four ";
listStaticSuffix[5] = "Five ";
listStaticSuffix[6] = "Six ";
listStaticSuffix[7] = "Seven ";
listStaticSuffix[8] = "Eight ";
listStaticSuffix[9] = "Nine ";
listStaticSuffix[10] = "Ten ";
listStaticSuffix[11] = "Eleven ";
listStaticSuffix[12] = "Twelve ";
listStaticSuffix[13] = "Thirteen ";
listStaticSuffix[14] = "Fourteen ";
listStaticSuffix[15] = "Fifteen ";
listStaticSuffix[16] = "Sixteen ";
listStaticSuffix[17] = "Seventeen ";
listStaticSuffix[18] = "Eighteen ";
listStaticSuffix[19] = "Nineteen ";
listStaticSuffix[20] = "Twenty ";
listStaticSuffix[30] = "Thirty ";
listStaticSuffix[40] = "Fourty ";
listStaticSuffix[50] = "Fifty ";
listStaticSuffix[60] = "Sixty ";
listStaticSuffix[70] = "Seventy ";
listStaticSuffix[80] = "Eighty ";
listStaticSuffix[90] = "Ninty ";
};
InrToWordConverter.LoadHelpofNotation = function () {
listHelpNotation[2] = "=1,000 (3 Trailing Zeros)";
listHelpNotation[3] = "=1,00,000 (5 Trailing Zeros)";
listHelpNotation[4] = "=1,00,00,000 (7 Trailing Zeros)";
listHelpNotation[5] = "=1,00,00,00,000 (9 Trailing Zeros)";
listHelpNotation[6] = "=1,00,00,00,00,000 (11 Trailing Zeros)";
listHelpNotation[7] = "=1,00,00,00,00,00,000 (13 Trailing Zeros)";
listHelpNotation[8] = "=1,00,00,00,00,00,00,000 (15 Trailing Zeros)";
listHelpNotation[9] = "=1,00,00,00,00,00,00,00,000 (17 Trailing Zeros)";
listHelpNotation[10] = "=1,00,00,00,00,00,00,00,00,000 (19 Trailing Zeros)";
listHelpNotation[11] = "=1,00,00,00,00,00,00,00,00,00,000 (21 Trailing Zeros)";
listHelpNotation[12] = "=1,00,00,00,00,00,00,00,00,00,00,000 (23 Trailing Zeros)";
listHelpNotation[13] = "=1,00,00,00,00,00,00,00,00,00,00,00,000 (25 Trailing Zeros)";
listHelpNotation[14] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,000 (27 Trailing Zeros)";
listHelpNotation[15] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (29 Trailing Zeros)";
listHelpNotation[16] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (31 Trailing Zeros)";
listHelpNotation[17] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (33 Trailing Zeros)";
listHelpNotation[18] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (35 Trailing Zeros)";
listHelpNotation[19] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (37 Trailing Zeros)";
listHelpNotation[20] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (39 Trailing Zeros)";
};
if (!String.trim) {
String.trim = function (str) {
var result = "";
var firstNonWhiteSpaceFound = false;
var startIndex = -1;
var endIndex = -1;
if (str) {
for (var i = 0; i < str.length; i++) {
if (firstNonWhiteSpaceFound === false) {
if (str[i] === ' ' || str[i] === '\t') {
continue;
}
else {
firstNonWhiteSpaceFound = true;
startIndex = i;
endIndex = i;
}
}
else {
if (str[i] === ' ' || str[i] === '\t') {
continue;
}
else {
endIndex = i;
}
}
}
if (startIndex !== -1 && endIndex !== -1) {
result = str.slice(startIndex, endIndex + 1);
}
}
return result;
};
}
Try this code with a Turkish currency compliant JavaScript
function dene() {
var inpt = document.getElementById("tar1").value;
var spt = inpt.split('');
spt.reverse();
var tek = ["", "Bir", "İki", "Üç", "Dört", "Beş", "Altı", "Yedi", "Sekiz", "Dokuz"];
var onlu = ["", "On", "Yirmi", "Otuz", "Kırk", "Elli", "Atmış", "Yetmiş", "Seksen", "Doksan"];
var Yuz = ["", "Yüz", "İkiYüz", "Üçyüz", "DörtYüz", "BeşYüz", "AltıYüz", "YediYüz", "SekizYüz", "DokuzYüz"];
var ska = ["", "", "", "", "Bin", "Milyon", "Milyar", "Trilyon", "Katrilyon", "Kentilyon"];
var i, j;
var bas3 = "";
var bas6 = "";
var bas9 = "";
var bas12 = "";
var total;
for(i = 0; i < 1; i++) {
bas3 += Yuz[spt[i+2]] + onlu[spt[i+1]] + tek[spt[i]];
bas6 += Yuz[spt[i+5]] + onlu[spt[i+4]] + tek[spt[i+3]] + ska[4];
bas9 += Yuz[spt[i+8]] + onlu[spt[i+7]] + tek[spt[i+6]] + ska[5];
bas12 += Yuz[spt[i+11]] + onlu[spt[i+10]] + tek[spt[i+9]] + ska[6];
if(inpt.length < 4) {
bas6 = '';
bas9 = '';
}
if(inpt.length > 6 && inpt.slice(5, 6) == 0) {
bas6 = bas6.replace(/Bin/g, '');
}
if(inpt.length < 7) {
bas9 = '';
}
if(inpt.length > 9 && inpt.slice(1,3) == 000){
bas9 = bas9.replace(/Milyon/g, '');
}
if(inpt.length < 10) {
bas12 = '';
}
}
total = bas12 + bas9 + bas6 + bas3;
total = total.replace(NaN, '');
total = total.replace(undefined, '');
document.getElementById('demo').innerHTML =
total;
}
Lot of good answers. I needed mine for Indian (South Asian) numbering system. I modified one of the codes above - attaching it here, in case, someone else needs this. In the Indian numbering system, groups after thousands are in in 2 digits, not 3 as in the western system.
var IS_SOUTH_ASIAN = true;
function int_to_words(int) {
if (int === 0) return 'zero';
var ONES_WORD = ['','one','two','three','four','five','six','seven','eight','nine','ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen'];
var TENS_WORD = ['','','twenty','thirty','fourty','fifty','sixty','seventy','eighty','ninety'];
var SCALE_WORD_WESTERN = ['','thousand','million','billion','trillion','quadrillion','quintillion','sextillion','septillion','octillion','nonillion'];
var SCALE_WORD_SOUTH_ASIAN = ['','thousand','lakh','crore','arab','kharab','neel','padma','shankh','***','***'];
var GROUP_SIZE = (typeof IS_SOUTH_ASIAN != "undefined" && IS_SOUTH_ASIAN) ? 2 : 3;
var SCALE_WORD = (typeof IS_SOUTH_ASIAN != "undefined" && IS_SOUTH_ASIAN) ? SCALE_WORD_SOUTH_ASIAN : SCALE_WORD_WESTERN;
// Return string of first three digits, padded with zeros if needed
function get_first_3(str) {
return ('000' + str).substr(-(3));
}
function get_first(str) { //-- Return string of first GROUP_SIZE digits, padded with zeros if needed, if group size is 2, make it size 3 by prefixing with a '0'
return (GROUP_SIZE == 2 ? '0' : '') + ('000' + str).substr(-(GROUP_SIZE));
}
// Return string of digits with first three digits chopped off
function get_rest_3(str) {
return str.substr(0, str.length - 3);
}
function get_rest(str) { // Return string of digits with first GROUP_SIZE digits chopped off
return str.substr(0, str.length - GROUP_SIZE);
}
// Return string of triplet convereted to words
function triplet_to_words(_3rd, _2nd, _1st) {
return (_3rd == '0' ? '' : ONES_WORD[_3rd] + ' hundred ') +
(_1st == '0' ? TENS_WORD[_2nd] : TENS_WORD[_2nd] && TENS_WORD[_2nd] + '-' || '') +
(ONES_WORD[_2nd + _1st] || ONES_WORD[_1st]); //-- 1st one returns one-nineteen - second one returns one-nine
}
// Add to result, triplet words with scale word
function add_to_result(result, triplet_words, scale_word) {
return triplet_words ? triplet_words + (scale_word && ' ' + scale_word || '') + ' ' + result : result;
}
function recurse (result, scaleIdx, first, rest) {
if (first == '000' && rest.length === 0) return result;
var newResult = add_to_result (result, triplet_to_words (first[0], first[1], first[2]), SCALE_WORD[scaleIdx]);
return recurse (newResult, ++scaleIdx, get_first(rest), get_rest(rest));
}
return recurse ('', 0, get_first_3(String(int)), get_rest_3(String(int)));
}
while this system does use a for loop, It uses US english and is fast, accurate, and expandable(you can add infinite values to the "th" var and they will be included).
This function grabs the 3 groups of numbers backwards so it can get the number groups where a , would normally separate them in the numeric form. Then each group of three numbers is added to an array with the word form of just the 3 numbers(ex: one hundred twenty three). It then takes that new array list, and reverses it again, while adding the th var of the same index to the end of the string.
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 ', 'hundred '];
var th = ['', 'thousand ','million ','billion ', 'trillion '];
function numberToWord(number){
var text = "";
var size = number.length;
var textList = [];
var textListCount = 0;
//get each 3 digit numbers
for(var i = number.length-1; i >= 0; i -= 3){
//get 3 digit group
var num = 0;
if(number[(i-2)]){num += number[(i-2)];}
if(number[(i-1)]){num += number[(i-1)];}
if(number[i]){num += number[i];}
//remove any extra 0's from begining of number
num = Math.floor(num).toString();
if(num.length == 1 || num < 20){
//if one digit or less than 20
textList[textListCount] = ones[num];
}else if(num.length == 2){
//if 2 digits and greater than 20
textList[textListCount] = tens[num[0]]+ones[num[1]];
}else if(num.length == 3){
//if 3 digits
textList[textListCount] = ones[num[0]]+tens[10]+tens[num[1]]+ones[num[2]];
}
textListCount++;
}
//add the list of 3 digit groups to the string
for(var i = textList.length-1; i >= 0; i--){
if(textList[i] !== ''){text += textList[i]+th[i];} //skip if the number was 0
}
return text;
}
This is also in response to naomik's excellent post! Unfortunately I don't have the rep to post in the correct place but I leave this here in case it can help anyone.
If you need British English written form you need to make some adaptions to the code. British English differs from the American in a couple of ways. Basically you need to insert the word 'and' in two specific places.
After a hundred assuming there are tens and ones. E.g One hundred and ten. One thousand and seventeen. NOT One thousand one hundred and.
In certain edges, after a thousand, a million, a billion etc. when there are no smaller units. E.g. One thousand and ten. One million and forty four. NOT One million and one thousand.
The first situation can be addressed by checking for 10s and 1s in the makeGroup method and appending 'and' when they exist.
makeGroup = ([ones,tens,huns]) => {
var adjective = this.num(ones) ? ' hundred and ' : this.num(tens) ? ' hundred and ' : ' hundred';
return [
this.num(huns) === 0 ? '' : this.a[huns] + adjective,
this.num(ones) === 0 ? this.b[tens] : this.b[tens] && this.b[tens] + '-' || '',
this.a[tens+ones] || this.a[ones]
].join('');
};
The second case is more complicated. It is equivalent to
add 'and' to 'a million, a thousand', or 'a billion' if the antepenultimate number is zero. e.g.
1,100,057 one million one hundred thousand and fifty seven.
5,000,006 five million and six
I think this could be implemented in #naomik's code through the use of a filter function but I wasn't able to work out how. In the end I settled on hackily looping through the returned array of words and using indexOf to look for instances where the word 'hundred' was missing from the final element.
I've just written paisa.js to do this, and it handles lakhs and crores correctly as well, can check it out. The core looks a bit like this:
const regulars = [
{
1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine'
},
{
2: 'twenty', 3: 'thirty', 4: 'forty', 5: 'fifty', 6: 'sixty', 7: 'seventy', 8: 'eighty', 9: 'ninety'
}
]
const exceptions = {
10: 'ten',
11: 'eleven',
12: 'twelve',
13: 'thirteen',
14: 'fourteen',
15: 'fifteen',
16: 'sixteen',
17: 'seventeen',
18: 'eighteen',
19: 'nineteen'
}
const partInWords = (part) => {
if (parseInt(part) === 0) return
const digits = part.split('')
const words = []
if (digits.length === 3) {
words.push([regulars[0][digits.shift()], 'hundred'].join(' '))
}
if (exceptions[digits.join('')]) {
words.push(exceptions[digits.join('')])
} else {
words.push(digits.reverse().reduce((memo, el, i) => {
memo.unshift(regulars[i][el])
return memo
}, []).filter(w => w).join(' '))
}
return words.filter(w => w.trim().length).join(' and ')
}
My solution is based on Juan Gaitán's solution for Indian currency, works up to crores.
function valueInWords(value) {
let ones = ['', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'];
let tens = ['twenty','thirty', 'forty','fifty', 'sixty', 'seventy', 'eighty', 'ninety'];
let digit = 0;
if (value < 20) return ones[value];
if (value < 100) {
digit = value % 10; //remainder
return tens[Math.floor(value/10)-2] + " " + (digit > 0 ? ones[digit] : "");
}
if (value < 1000) {
return ones[Math.floor(value/100)] + " hundred " + (value % 100 > 0 ? valueInWords(value % 100) : "");
}
if (value < 100000) {
return valueInWords(Math.floor(value/1000)) + " thousand " + (value % 1000 > 0 ? valueInWords(value % 1000) : "");
}
if (value < 10000000) {
return valueInWords(Math.floor(value/100000)) + " lakh " + (value % 100000 > 0 ? valueInWords(value % 100000) : "");
}
return valueInWords(Math.floor(value/10000000)) + " crore " + (value % 10000000 > 0 ? valueInWords(value % 10000000) : "");
}
function numberToEnglish( n ) {
var string = n.toString(), units, tens, scales, start, end, chunks, chunksLen, chunk, ints, i, word, words, and = 'and';
/* Remove spaces and commas */
string = string.replace(/[, ]/g,"");
/* Is number zero? */
if( parseInt( string ) === 0 ) {
return 'zero';
}
/* Array of units as words */
units = [ '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' ];
/* Array of tens as words */
tens = [ '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety' ];
/* Array of scales as words */
scales = [ '', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quatttuor-decillion', 'quindecillion', 'sexdecillion', 'septen-decillion', 'octodecillion', 'novemdecillion', 'vigintillion', 'centillion' ];
/* Split user argument into 3 digit chunks from right to left */
start = string.length;
chunks = [];
while( start > 0 ) {
end = start;
chunks.push( string.slice( ( start = Math.max( 0, start - 3 ) ), end ) );
}
/* Check if function has enough scale words to be able to stringify the user argument */
chunksLen = chunks.length;
if( chunksLen > scales.length ) {
return '';
}
/* Stringify each integer in each chunk */
words = [];
for( i = 0; i < chunksLen; i++ ) {
chunk = parseInt( chunks[i] );
if( chunk ) {
/* Split chunk into array of individual integers */
ints = chunks[i].split( '' ).reverse().map( parseFloat );
/* If tens integer is 1, i.e. 10, then add 10 to units integer */
if( ints[1] === 1 ) {
ints[0] += 10;
}
/* Add scale word if chunk is not zero and array item exists */
if( ( word = scales[i] ) ) {
words.push( word );
}
/* Add unit word if array item exists */
if( ( word = units[ ints[0] ] ) ) {
words.push( word );
}
/* Add tens word if array item exists */
if( ( word = tens[ ints[1] ] ) ) {
words.push( word );
}
/* Add 'and' string after units or tens integer if: */
if( ints[0] || ints[1] ) {
/* Chunk has a hundreds integer or chunk is the first of multiple chunks */
if( ints[2] || ! i && chunksLen ) {
words.push( and );
}
}
/* Add hundreds word if array item exists */
if( ( word = units[ ints[2] ] ) ) {
words.push( word + ' hundred' );
}
}
}
return words.reverse().join( ' ' );
}
// - - - - - Tests - - - - - -
function test(v) {
var sep = ('string'==typeof v)?'"':'';
console.log("numberToEnglish("+sep + v.toString() + sep+") = "+numberToEnglish(v));
}
test(2);
test(721);
test(13463);
test(1000001);
test("21,683,200,000,621,384");
For those who are looking for imperial/english naming conventions.
Based on #Salman's answer
var a = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
var b = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
function inWords (num) {
if ((num = num.toString()).length > 12) return 'overflow';
n = ('00000000000' + num).substr(-12).match(/^(\d{3})(\d{3})(\d{3})(\d{1})(\d{2})$/);
if (!n) return; var str = '';
str += (n[1] != 0) ? (Number(n[1]) > 99 ? this.a[Number(n[1][0])] + 'hundred ' : '') + (a[Number(n[1])] || b[n[1][1]] + ' ' + a[n[1][2]]) + 'billion ' : '';
str += (n[2] != 0) ? (Number(n[2]) > 99 ? this.a[Number(n[2][0])] + 'hundred ' : '') + (a[Number(n[2])] || b[n[2][1]] + ' ' + a[n[2][2]]) + 'million ' : '';
str += (n[3] != 0) ? (Number(n[3]) > 99 ? this.a[Number(n[3][0])] + 'hundred ' : '') + (a[Number(n[3])] || b[n[3][1]] + ' ' + a[n[3][2]]) + 'thousand ' : '';
str += (n[4] != 0) ? (a[Number(n[4])] || b[n[4][0]] + ' ' + a[n[4][1]]) + 'hundred ' : '';
str += (Number(n[5]) !== 0) ? ((str !== '') ? 'and ' : '') +
(this.a[Number(n[5])] || this.b[n[5][0]] + ' ' +
this.a[n[5][1]]) + '' : '';
return str;
}
document.getElementById('number').onkeyup = function () {
document.getElementById('words').innerHTML = inWords(document.getElementById('number').value);
};
<span id="words"></span>
<input id="number" type="text" />
Cleanest and easiest approach that came to mind:
const numberText = {
1: 'one',
2: 'two',
3: 'three',
4: 'four',
5: 'five',
6: 'six',
7: 'seven',
8: 'eight',
9: 'nine',
10: 'ten',
11: 'eleven',
12: 'twelve',
13: 'thirteen',
14: 'fourteen',
15: 'fifteen',
16: 'sixteen',
17: 'seventeen',
18: 'eighteen',
19: 'nineteen',
20: 'twenty',
30: 'thirty',
40: 'forty',
50: 'fifty',
60: 'sixty',
70: 'seventy',
80: 'eighty',
90: 'ninety',
100: 'hundred',
1000: 'thousand',
}
const numberValues = Object.keys(numberText)
.map((val) => Number(val))
.sort((a, b) => b - a)
const convertNumberToEnglishText = (n) => {
if (n === 0) return 'zero'
if (n < 0) return 'negative ' + convertNumberToEnglishText(-n)
let num = n
let text = ''
for (const numberValue of numberValues) {
const count = Math.trunc(num / numberValue)
if (count < 1) continue
if (numberValue >= 100) text += convertNumberToEnglishText(count) + ' '
text += numberText[numberValue] + ' '
num -= count * numberValue
}
if (num !== 0) throw Error('Something went wrong!')
return text.trim()
}
Probably the simplest one I got and used was from Ben E. I made modifications to his code since it would only return for example 'Five Hundred' when you try to convert 500,000.00. I just added a line of conditional code to fix it. Also added the provision for giving out the last two decimal places. I'm now using it to convert the amount to words when printing checks. Here was my revision added to it:
if (Math.floor((number%(100*Math.pow(1000,i))/Math.pow(1000,i))) == 0) {
word = first[Math.floor(tempNumber/(100*Math.pow(1000,i)))] + 'Hundred ' + mad[i]
+ ' ' + word;
} else {
I'm having a hard time pasting the code here but let me know if you need any clarifications
answared by #pramod kharade
simplified
function NumToWord(inputNumber) {
var str = new String(inputNumber)
var splt = str.split("");
var rev = splt.reverse();
var once = ['Zero', ' One', ' Two', ' Three', ' Four', ' Five', ' Six', ' Seven', ' Eight', ' Nine'];
var twos = ['Ten', ' Eleven', ' Twelve', ' Thirteen', ' Fourteen', ' Fifteen', ' Sixteen', ' Seventeen', ' Eighteen', ' Nineteen'];
var tens = ['', 'Ten', ' Twenty', ' Thirty', ' Forty', ' Fifty', ' Sixty', ' Seventy', ' Eighty', ' Ninety'];
numLength = rev.length;
var word = new Array();
var j = 0;
for (i = 0; i < numLength; i++) {
switch (i) {
case 0:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = '' + once[rev[i]];
}
word[j] = word[j];
break;
case 1:
aboveTens();
break;
case 2:
if (rev[i] == 0) {
word[j] = '';
}
else if ((rev[i - 1] == 0) || (rev[i - 2] == 0)) {
word[j] = once[rev[i]] + " Hundred ";
}
else {
word[j] = once[rev[i]] + " Hundred and";
}
break;
case 3:
if (rev[i] == 0 || rev[i + 1] == 1) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if ((rev[i + 1] != 0) || (rev[i] > 0)) {
word[j] = word[j] + " Thousand";
}
break;
case 4:
aboveTens();
break;
case 5:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if (rev[i + 1] !== '0' || rev[i] > '0') {
word[j] = word[j] + " Lakh";
}
break;
case 6:
aboveTens();
break;
case 7:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if (rev[i + 1] !== '0' || rev[i] > '0') {
word[j] = word[j] + " Crore";
}
break;
case 8:
aboveTens();
break;
default: break;
}
j++;
}
function aboveTens() {
if (rev[i] == 0) { word[j] = ''; }
else if (rev[i] == 1) { word[j] = twos[rev[i - 1]]; }
else { word[j] = tens[rev[i]]; }
}
word.reverse();
var finalOutput = '';
for (i = 0; i < numLength; i++) {
finalOutput = finalOutput + word[i];
}
return finalOutput;
}
console.log(NumToWord(123))
console.log(NumToWord(12345678))
console.log(NumToWord(12334543))
console.log(NumToWord(6789876123))
Convertirlos en Español
class Converter {
constructor() {
this.unit = ['CERO', 'UN', 'DOS', 'TRES', 'CUATRO', 'CINCO', 'SEIS', 'SIETE', 'OCHO', 'NUEVE'];
this.units = ['CERO', 'UNO', 'DOS', 'TRES', 'CUATRO', 'CINCO', 'SEIS', 'SIETE', 'OCHO', 'NUEVE'];
this.tenToSixteen = ['DIEZ', 'ONCE', 'DOCE', 'TRECE', 'CATORCE', 'QUINCE', 'DIECISEIS'];
this.tens = ['TREINTA', 'CUARENTA', 'CINCUENTA', 'SESENTA', 'SETENTA', 'OCHENTA', 'NOVENTA'];
this.monedaSingular = " PESO";
this.monedaPlural = " PESOS";
this.monedaMillon = " DE PESOS";
this.centavoSingular = " CENTAVO"
this.centavoPlural = " CENTAVOS"
this.elMessage = document.getElementById('message');
this.addListener();
}
addListener() {
let elInput = document.getElementById('field-number');
elInput.addEventListener('keyup', () => {
if (elInput.value !== '') {
this.convertToText(elInput.value);
} else {
this.elMessage.innerText = '';
}
});
}
convertToText(number) {
number = this.deleteZerosLeft(number);
if (!this.validateNumber(number)) {
this.elMessage.innerText = 'Sólo se aceptan números enteros positivos.';
return;
}
let num = number;
number = number.split(".")[0];
let entero = this.getName(number);
let moneda;
if (parseInt(number) == 1) {
//this.elMessage.innerText =
moneda = entero + this.monedaSingular;
} else {
moneda = entero + this.monedaPlural;
}
if (num.indexOf('.') >= 0) {
let d = num.split(".")[1];
d = this.getName(d);
if (parseInt(d) == 0) {
moneda = moneda;
} else if (parseInt(d) == 1) {
moneda = moneda + " CON " + d + " " + this.centavoSingular;
} else {
moneda = moneda + " CON " + d + " " + this.centavoPlural;
}
}
this.elMessage.innerText = moneda;
}
// Elimina los ceros a la izquierda
deleteZerosLeft(number) {
let i = 0;
let isZero = true;
for (i = 0; i < number.length; i++) {
if (number.charAt(i) != 0) {
isZero = false;
break;
}
}
return isZero ? '0' : number.substr(i);
}
validateNumber(number) {
// Validar que la cadena sea un número y que no esté vacía
if (isNaN(number) || number === '') {
return false;
}
// Validar que el número no sea negativo
if (number.indexOf('-') >= 0) {
return false;
}
return true;
}
getName(number) {
number = this.deleteZerosLeft(number);
if (number.length === 1) {
return this.getUnits(number);
}
if (number.length === 2) {
return this.getTens(number);
}
if (number.length === 3) {
return this.getHundreds(number);
}
if (number.length < 7) {
return this.getThousands(number);
}
if (number.length < 13) {
return this.getPeriod(number, 6, 'MILLON');
}
if (number.length < 19) {
return this.getPeriod(number, 12, 'BILLON');
}
return 'Número demasiado grande.';
}
getUnits(number) {
let numberInt = parseInt(number);
return this.unit[numberInt];
}
getTens(number) {
// Obtener las unidades
let units = number.charAt(1);
if (number < 17) {
return this.tenToSixteen[number - 10];
}
if (number < 20) {
return 'DIECI' + this.getUnits(units);
}
// Nombres especiales
switch (number) {
case '20':
return 'VEINTE';
case '22':
return 'VEINTIDOS';
case '23':
return 'VEINTITRES';
case '26':
return 'VEINTISEIS';
}
if (number < 30) {
return 'VEINTI' + this.getUnits(units);
}
let name = this.tens[number.charAt(0) - 3];
if (units > 0) {
name += ' Y ' + this.getUnits(units);
}
return name;
}
getHundreds(number) {
let name = '';
// Obtener las centenas
let hundreds = number.charAt(0);
// Obtener las decenas y unidades
let tens = number.substr(1);
if (number == 100) {
return 'CIEN';
}
// Nombres especiales
switch(hundreds) {
case '1':
name = 'CIENTO';
break;
case '5':
name = 'QUINIENTOS';
break;
case '7':
name = 'SETECIENTOS';
break;
case '9':
name = 'NOVECIENTOS';
}
if (name === '') {
name = this.getUnits(hundreds) + 'CIENTOS';
}
if (tens > 0) {
name += ' ' + this.getName(tens);
}
return name;
}
getThousands(number) {
let name = 'MIL';
// Obtener cuantos dígitos están en los miles
let thousandsLength = number.length - 3;
// Obtener los miles
let thousands = number.substr(0, thousandsLength);
// Obtener las centenas, decenas y unidades
let hundreds = number.substr(thousandsLength);
if (thousands > 1) {
// Se reemplaza la palabra uno por un en numeros como 21000, 31000, 41000, etc.
name = this.getName(thousands).replace('UNO', 'UN') + ' MIL';
}
if (hundreds > 0) {
name += ' ' + this.getName(hundreds);
}
return name;
}
// Obtiene periodos, por ejemplo: millones, billones, etc.
getPeriod(number, digitsToTheRight, periodName) {
let name = 'UN ' + periodName;
// Obtener cuantos dígitos están dentro del periodo
let periodLength = number.length - digitsToTheRight;
// Obtener los dítos del periodo
let periodDigits = number.substr(0, periodLength);
// Obtener los digitos previos al periodo
let previousDigits = number.substr(periodLength);
if (periodDigits > 1) {
name = this.getName(periodDigits).replace('UNO', 'UN') + ' ' + periodName.replace('Ó', 'O') + 'ES';
}
if (previousDigits > 0) {
name += ' ' + this.getName(previousDigits);
}
return name;
}
}
new Converter();
I have a array like
var abc = ["mon","Thu","Fri","Tue","Wed","Sun","Sat"]
So next I want these days in order like
["mon","Tue","Wed","Thu","Fri","Sat","Sun"]
Is there any inbuilt functions or any logic for it?
I used a map object to be used along with a sort function .. pretty easy.
var arrayOfDays = ["Mon","Thu","Fri","Tue","Wed","Sun","Sat"]; //array to be sorted
//int this map, define the "correct" order of days
var map = {
"Sun" : 0,
"Mon" : 1,
"Tue" : 2,
"Wed" : 3,
"Thu" : 4,
"Fri" : 5,
"Sat" : 6,
}
function dateSort(array) //function to sort the array
{
for(i = 0 ; i < array.length ; i++)
for(j = i + 1 ; j < array.length ; j++)
{
if(map[array[i]] > map[array[j]])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
It can be invoked as follows:
datesort(arrayOfDays);
I tested it by printing the values of array of dates before calling the function and after:
Before: Mon Thu Fri Tue Wed Sun Sat
After: Sun Mon Tue Wed Thu Fri Sat
EDIT: As suggested by others, a version using Array.sort() - though avoid it if you are a beginner.
Define a custom compare function:
function dateCompare(d1, d2)
{
if(map[d1] == map[d2])
return 0;
return (map[d1] < map[d2]) ? -1 : 1;
}
Invoke as:
arrayOfDays.sort(dateCompare);
As indicated by others, you need to use square brackets for arrays, not curly ones:
var abc = ["mon","Thu","Fri","Tue","Wed","Sun","Sat"];
There is no predefined method that recognizes weekdays, but you can just compare given day names to a list that is in the correct order, like this:
function compareDayNames(day1, day2) {
var weekdays = ',monday,tuesday,wednesday,thursday,friday,saturday,sunday';
return weekdays.indexOf(',' + day1.toLowerCase())
- weekdays.indexOf(',' + day2.toLowerCase());
}
var abc = ["mon","Thu","Fri","Tue","Wed","Sun","Sat"];
abc.sort(compareDayNames);
console.log('Sorted: ' + abc.join(','));
Output in the console is:
Sorted: mon,Tue,Wed,Thu,Fri,Sat,Sun
This function also sorts longer and shorter names well:
var abc = ['Satur','Tu', 'W', 'M', 'Thurs'];
abc.sort(compareDayNames);
console.log('Sorted: ' + abc.join(','));
Output:
Sorted: M,Tu,W,Thurs,Satur
EDIT:
If you want to throw an error when an invalid day name is provided, or a name that is less than 2 characters (because T and S are ambiguous), then rewrite the compare function as follows:
function compareDayNames(day1, day2) {
var weekdays = ',monday,tuesday,wednesday,thursday,friday,saturday,sunday';
function dayNumber(day) {
var pos = weekdays.indexOf(',' + day.toLowerCase());
if (pos === -1 || day.length < 2) {
throw '"' + day + '" is not a valid day name';
}
return pos;
}
return dayNumber(day1) - dayNumber(day2);
}
$(document).ready(function () {
var ndays = "";
var days = "Sat,Fri,mon,Thu,Tue,Wed,Sun";
var dys = days.split(",");
debugger;
for (var i = 0; i < dys.length; i++) {
switch (dys[i]) {
case "mon":
ndays = ndays + ",1";
break;
case "Tue":
ndays = ndays + ",2";
break;
case "Wed":
ndays = ndays + ",3";
break;
case "Thu":
ndays = ndays + ",4";
break;
case "Fri":
ndays = ndays + ",5";
break;
case "Sat":
ndays = ndays + ",6";
break;
default:
ndays = ndays + ",7";
break;
}
alert(ndays);
}
var cDays = "";
var wdays = ndays.split(",").sort();
for (var s = 0; s < wdays.length; s++) {
//alert(wdays[s]);
debugger;
if (wdays[s] === "1") {
cDays = "Mon";
}
else if (wdays[s] === "2") {
cDays = cDays + ",Tue";
}
else if (wdays[s] === "3") {
cDays = cDays + ",Wed";
}
else if (wdays[s] === "4") {
cDays = cDays + ",Thu";
}
else if (wdays[s] === "5") {
cDays = cDays + ",Fri";
}
else if (wdays[s] === "6") {
cDays = cDays + ",Sat";
}
else {
cDays = cDays + ",Sun";
}
}
});
There is no inbuilt function for it, you need to write your own logic as suggested in other answers. You can create one common function to compare two array's as...
function compareDays(wrongSquence , rightSequence) {
var i=0;
for(i=0;i<wrongSquence.length;i++) {
if(wrongSquence [i] != rightSequence[i]) {
wrongSquence [i] = rightSequence[i];
}
}
return wrongSquence;
}
//e.g....
var abc = ["mon","Thu","Fri","Tue","Wed","Sun","Sat"],
outputFormat = ["mon","Tue","Wed","Thu","Fri","Sat","Sun"];
var correctArray = compareDays(abc, outputFormat);
console.log(correctArray); // check output...
Mobiscroll date picker
every year should ends with reset value 00-000-0000, the reset value is achieved when i click the reset button. how to achieve this.
+----+-----+------+
| 31 | dec | 2014 |
| 00 | 000 | 0000 | ----->reset value
| 01 | jan | 2015 |
| 02 | jan | 2015 |
+----+-----+------+
--------------------
|ok| |reset| |cancel|
--------------------
To add reset value in the date picker scroll view. modify few lines of code in
mobiscroll.util.datetime.js, mobiscroll.datetimebase.js
In mobiscroll.datetimebase.js,
under variable defaults={}, add partialDate : false,
add reset values in a wheel generating loop: for (k = 0; k < 3; k++) {},
if (s.partialDate)
{
keys.push(-1);
values.push('0000');
}
replace following codes in a mobiscroll.datetimebase.js
formatValue: function (d) {
//return datetime.formatDate(format, getDate(d), s);
//KKN
if (d[o["m"]] != "-1" && d[o["d"]] != "0" )
{
datetime.partialDate = false;
return datetime.formatDate(format, getDate(d), s);
}
else
{
datetime.partialDate = true;
var tempDate = [],
hideDate = false,
hideMonth = false;
$.each(['y', 'm', 'd', 'a', 'h', 'i', 's'], function (x, i) {
tempDate[o[i]] = d[o[i]];
});
if (d[o["m"]] == "-1")
{
//datetime.partialDateFormat = yy;
tempDate[o["m"]] = "0";
tempDate[o["d"]] = "1";
hideMonth = true;
hideDate = true;
}else if (d[o["d"]] == "0"){
//datetime.partialDateFormat = MM-yy;
tempDate[o["d"]] = "1";
hideDate = true;
}
//var dt = getDate (tempDate);
var newDt = datetime.formatDate(format, getDate(tempDate), s, hideDate, hideMonth);
datetime.partialDateFormat = s.partialDateFormat;
return newDt;
}
//return datetime.formatPartialDate(format, d, s ,o);
},
parseValue: function (val) {
if (!val) {
innerValues = {};
}
var datValue = getArray(val ? datetime.parseDate(format, val, s) : (s.defaultValue || new Date()), !!val && !!val.getTime);
var seperator = "-";
if (format.indexOf ('/') > 0){
seperator = "/";
}
var dateArray = val.split(seperator);
switch (dateArray.length)
{
case 1: //Year Only
datValue[o["d"]] = 0;
datValue[o["m"]] = -1;
break;
case 2: //Month & Year
datValue[o["d"]] = 0;
break;
}
return datValue;
},
validate: function (dw, i, time, dir) {
//KKN
var temp = [],
hideDate = false,
hideMonth = false;
var d = inst.getArrayVal(true);
if (s.partialDate)
{
hideDate = false,
hideMonth = false;
$.each(['y', 'm', 'd', 'a', 'h', 'i', 's'], function (x, i) {
temp[o[i]] = d[o[i]];
});
if (d[o["m"]] == "-1")
{
temp[o["m"]] = "0";
temp[o["d"]] = "1";
hideMonth = true;
hideDate = true;
}else if (d[o["d"]] == "0"){
//datetime.partialDateFormat = MM-yy;
temp[o["d"]] = "1";
hideDate = true;
}
//return true;
}
else
{
var validated = getClosestValidDate(getDate(inst.getArrayVal(true)), dir),
temp = getArray(validated);
}
y = get(temp, 'y'),
m = get(temp, 'm'),
minprop = true,
maxprop = true;
$.each(['y', 'm', 'd', 'a', 'h', 'i', 's'], function (x, i) {
if (o[i] !== undefined) {
var min = mins[i],
max = maxs[i],
maxdays = 31,
val = get(temp, i),
t = $('.dw-ul', dw).eq(o[i]);
if (i == 'd') {
maxdays = s.getMaxDayOfMonth(y, m);
max = maxdays;
if (regen) {
$('.dw-li', t).each(function () {
var that = $(this),
d = that.data('val'),
w = s.getDate(y, m, d).getDay(),
str = dord.replace(/[my]/gi, '').replace(/dd/, (d < 10 ? '0' + d : d) + (s.daySuffix || '')).replace(/d/, d + (s.daySuffix || ''));
$('.dw-i', that).html(str.match(/DD/) ? str.replace(/DD/, '<span class="dw-day">' + s.dayNames[w] + '</span>') : str.replace(/D/, '<span class="dw-day">' + s.dayNamesShort[w] + '</span>'));
});
}
}
if (minprop && mind) {
min = f[i](mind);
}
if (maxprop && maxd) {
max = f[i](maxd);
}
if (i != 'y') {
var i1 = getIndex(t, min),
i2 = getIndex(t, max);
$('.dw-li', t).removeClass('dw-v').slice(i1, i2 + 1).addClass('dw-v');
if (i == 'd') { // Hide days not in month
//$('.dw-li', t).removeClass('dw-h').slice(maxdays).addClass('dw-h');
if (s.partialDate){
if (hideMonth)
{
$('.dw-li', t).removeClass('dw-h').slice(1).addClass('dw-h');
}
else{
$('.dw-li', t).removeClass('dw-h').slice(maxdays + 1).addClass('dw-h');
}
}
else
{
$('.dw-li', t).removeClass('dw-h').slice(maxdays).addClass('dw-h');
}
}
}
if (val < min) {
val = min;
}
if (val > max) {
val = max;
}
if (minprop) {
minprop = val == min;
}
if (maxprop) {
maxprop = val == max;
}
// Disable some days
if (i == 'd') {
var first = s.getDate(y, m, 1).getDay(),
idx = {};
// Set invalid indexes
validateDates(invalid, y, m, first, maxdays, idx, 1);
// Delete indexes which are valid
validateDates(valid, y, m, first, maxdays, idx, 0);
$.each(idx, function (i, v) {
if (v) {
$('.dw-li', t).eq(i).removeClass('dw-v');
}
});
}
}
});
// Invalid times
if (hasTime) {
$.each(['a', 'h', 'i', 's'], function (i, v) {
var val = get(temp, v),
d = get(temp, 'd'),
t = $('.dw-ul', dw).eq(o[v]);
if (o[v] !== undefined) {
validateTimes(invalid, i, v, temp, y, m, d, t, 0);
validateTimes(valid, i, v, temp, y, m, d, t, 1);
// Get valid value
validValues[i] = +inst.getValidCell(val, t, dir).val;
}
});
}
if (hideMonth)
{
temp[o["m"]] = "-1";
temp[o["d"]] = "0";
}else if (hideDate){
//datetime.partialDateFormat = MM-yy;
temp[o["d"]] = "0";
}
inst._tempWheelArray = temp;
}
and in mobiscroll.util.datetime.js, replace following lines
(function ($, undefined) {
var ms = $.mobiscroll;
ms.datetime = {
defaults: {
shortYearCutoff: '+10',
monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
dayNamesMin: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
amText: 'am',
pmText: 'pm',
getYear: function (d) { return d.getFullYear(); },
getMonth: function (d) { return d.getMonth(); },
getDay: function (d) { return d.getDate(); },
getDate: function (y, m, d, h, i, s, u) { return new Date(y, m, d, h || 0, i || 0, s || 0, u || 0); },
getMaxDayOfMonth: function (y, m, o) { return 32 - new Date(y, m, 32).getDate(); },
getWeekNumber: function (d) {
// Copy date so don't modify original
d = new Date(d);
d.setHours(0, 0, 0);
// Set to nearest Thursday: current date + 4 - current day number
// Make Sunday's day number 7
d.setDate(d.getDate() + 4 - (d.getDay() || 7));
// Get first day of year
var yearStart = new Date(d.getFullYear(), 0, 1);
// Calculate full weeks to nearest Thursday
return Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
}
},
/**
* Format a date into a string value with a specified format.
* #param {String} format Output format.
* #param {Date} date Date to format.
* #param {Object} [settings={}] Settings.
* #return {String} Returns the formatted date string.
*/
formatDate: function (format, date, settings, hideDate, hideMonth) {
var newformat = format;
if (!date) {
return null;
}
var s = $.extend({}, ms.datetime.defaults, settings),
look = function (m) { // Check whether a format character is doubled
var n = 0;
while (i + 1 < format.length && format.charAt(i + 1) == m) {
n++;
i++;
}
return n;
},
f1 = function (m, val, len) { // Format a number, with leading zero if necessary
var n = '' + val;
if (look(m)) {
while (n.length < len) {
n = '0' + n;
}
}
return n;
},
f2 = function (m, val, s, l) { // Format a name, short or long as requested
return (look(m) ? l[val] : s[val]);
},
f3 = function (m){
look(m);
if (newformat.indexOf('/') > 0 ){
newformat = newformat.replace( m +'/', '');
}
else
{
newformat = newformat.replace( m +'-', '');
}
newformat = newformat.replace( m, '');
if (format.charAt(i+1) == "/" ||format.charAt(i+1) == "-"){//Skip Separator
i++;
}
return '';
},
i,
year,
output = '',
literal = false;
//return s.getPartialMonth(date, format);
for (i = 0; i < format.length; i++) {
if (literal) {
if (format.charAt(i) == "'" && !look("'")) {
literal = false;
} else {
output += format.charAt(i);
}
} else {
switch (format.charAt(i)) {
case 'd':
if (hideDate)
{
output += f3('d');
}
else
{
output += f1('d', s.getDay(date), 2);
}
break;
case 'D':
if (hideDate)
{
output += f3('D');
}
else
{
output += f2('D', date.getDay(), s.dayNamesShort, s.dayNames);
}
break;
case 'o':
output += f1('o', (date.getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000, 3);
break;
case 'm':
if (hideMonth)
{
output += f3('m');
}
else
{
output += f1('m', s.getMonth(date) + 1, 2);
}
break;
case 'M':
if (hideMonth)
{
output += f3('M');
}
else
{
output += f2('M', s.getMonth(date), s.monthNamesShort, s.monthNames);
}
break;
case 'y':
year = s.getYear(date);
output += (look('y') ? year : (year % 100 < 10 ? '0' : '') + year % 100);
//output += (look('y') ? date.getFullYear() : (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
break;
case 'h':
var h = date.getHours();
output += f1('h', (h > 12 ? (h - 12) : (h === 0 ? 12 : h)), 2);
break;
case 'H':
output += f1('H', date.getHours(), 2);
break;
case 'i':
output += f1('i', date.getMinutes(), 2);
break;
case 's':
output += f1('s', date.getSeconds(), 2);
break;
case 'a':
output += date.getHours() > 11 ? s.pmText : s.amText;
break;
case 'A':
output += date.getHours() > 11 ? s.pmText.toUpperCase() : s.amText.toUpperCase();
break;
case "'":
if (look("'")) {
output += "'";
} else {
literal = true;
}
break;
default:
output += format.charAt(i);
}
}
}
ms.partialDateFormat = newformat;
return output;
},
/**
* Format a date into a string value with a specified format.
* #param {String} format Output format.
* #param {Date} date Date to format.
* #param {Object} [settings={}] Settings.
* #return {String} Returns the formatted date string.
*/
formatPartialDate: function (format, date, settings, o) {
if (!date) {
return null;
}
var tempDate = [],
hideDate = false,
hideMonth = false;
$.each(['y', 'm', 'd', 'a', 'h', 'i', 's'], function (x, i) {
tempDate[o[i]] = date[o[i]];
});
if (date[o["m"]] == "-1")
{
tempDate[o["m"]] = "0";
tempDate[o["d"]] = "1";
hideMonth = true;
hideDate = true;
}else if (date[o["d"]] == "0"){
tempDate[o["d"]] = "1";
hideDate = true;
}
var t2 = ms.getDate(tempDate);
var t1 = new Date();
//var output = ms.formatDate(format, settings.getDate(tempDate), settings, hideDate, hideMonth);
var output = ms.formatDate(format, tempDate, settings, hideDate, hideMonth);
return output;
},
/**
* Extract a date from a string value with a specified format.
* #param {String} format Input format.
* #param {String} value String to parse.
* #param {Object} [settings={}] Settings.
* #return {Date} Returns the extracted date.
*/
parseDate: function (format, value, settings) {
var s = $.extend({}, ms.datetime.defaults, settings),
def = s.defaultValue || new Date();
if (!format || !value) {
return def;
}
// If already a date object
if (value.getTime) {
return value;
}
value = (typeof value == 'object' ? value.toString() : value + '');
var seperator = "-";
if (format.indexOf ('/') > 0){
seperator = "/";
}
var dateArray = value.split(seperator);
//else (value)
var shortYearCutoff = s.shortYearCutoff,
year = s.getYear(def),
month = s.getMonth(def) + 1,
day = s.getDay(def),
doy = -1,
hours = def.getHours(),
minutes = def.getMinutes(),
seconds = 0, //def.getSeconds(),
ampm = -1,
literal = false, // Check whether a format character is doubled
lookAhead = function (match) {
var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
if (matches) {
iFormat++;
}
return matches;
},
getNumber = function (match) { // Extract a number from the string value
lookAhead(match);
var size = (match == '#' ? 14 : (match == '!' ? 20 : (match == 'y' ? 4 : (match == 'o' ? 3 : 2)))),
digits = new RegExp('^\\d{1,' + size + '}'),
num = value.substr(iValue).match(digits);
if (!num) {
return 0;
}
iValue += num[0].length;
return parseInt(num[0], 10);
},
getName = function (match, s, l) { // Extract a name from the string value and convert to an index
var names = (lookAhead(match) ? l : s),
i;
for (i = 0; i < names.length; i++) {
if (value.substr(iValue, names[i].length).toLowerCase() == names[i].toLowerCase()) {
iValue += names[i].length;
return i + 1;
}
}
return 0;
},
checkLiteral = function () {
if (value.charAt(iValue) == '/' || value.charAt(iValue) == '-')
iValue++;
},
iValue = 0,
iFormat;
for (iFormat = 0; iFormat < format.length; iFormat++) {
if (literal) {
if (format.charAt(iFormat) == "'" && !lookAhead("'")) {
literal = false;
} else {
checkLiteral();
}
} else {
switch (format.charAt(iFormat)) {
case 'd':
if (dateArray.length <= 2){
day = 1;
//iValue++;
}
else{
day = getNumber('d');
}
break;
case 'D':
getName('D', s.dayNamesShort, s.dayNames);
break;
case 'o':
doy = getNumber('o');
break;
case 'm':
if (dateArray.length == 1){
month = 1;
//iValue++;
}
else
{
month = getNumber('m');
}
break;
case 'M':
if (dateArray.length == 1){
month = 1;
//iValue++;
}
else
{
month = getName('M', s.monthNamesShort, s.monthNames);
}
break;
case 'y':
year = getNumber('y');
break;
case 'H':
hours = getNumber('H');
break;
case 'h':
hours = getNumber('h');
break;
case 'i':
minutes = getNumber('i');
break;
case 's':
seconds = getNumber('s');
break;
case 'a':
ampm = getName('a', [s.amText, s.pmText], [s.amText, s.pmText]) - 1;
break;
case 'A':
ampm = getName('A', [s.amText, s.pmText], [s.amText, s.pmText]) - 1;
break;
case "'":
if (lookAhead("'")) {
checkLiteral();
} else {
literal = true;
}
break;
default:
checkLiteral();
}
}
}
if (year < 100) {
year += new Date().getFullYear() - new Date().getFullYear() % 100 +
(year <= (typeof shortYearCutoff != 'string' ? shortYearCutoff : new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)) ? 0 : -100);
}
if (doy > -1) {
month = 1;
day = doy;
do {
var dim = 32 - new Date(year, month - 1, 32).getDate();
if (day <= dim) {
break;
}
month++;
day -= dim;
} while (true);
}
hours = (ampm == -1) ? hours : ((ampm && hours < 12) ? (hours + 12) : (!ampm && hours == 12 ? 0 : hours));
var date = s.getDate(year, month - 1, day, hours, minutes, seconds);
if (s.getYear(date) != year || s.getMonth(date) + 1 != month || s.getDay(date) != day) {
return def; // Invalid date
}
return date;
}
};
// #deprecated since 2.11.0, backward compatibility code
// ---
ms.formatDate = ms.datetime.formatDate;
ms.parseDate = ms.datetime.parseDate;
ms.formatPartialDate = ms.datetime.formatPartialDate;
ms.getDate = ms.datetime.getDate;
ms.partialDate = true;
ms.partialDateFormat = ms.datetime.partialDateFormat; })(jQuery);
to enable a partial date picker add partialDate: true, whenever you want to enable a partial date picker.
I'm writing some code that converts a given number into words, here's what I have got after googling. But I think it's a bit too long for such a simple task.
Two Regular Expressions and two for loops, I want something simpler.
I am trying to achieve this in as few lines of code as possible. here's what I've come up with so far:
Any suggestions?
var th = ['','thousand','million', 'billion','trillion'];
var dg = ['zero','one','two','three','four', 'five','six','seven','eight','nine'];
var tn = ['ten','eleven','twelve','thirteen', 'fourteen','fifteen','sixteen', 'seventeen','eighteen','nineteen'];
var tw = ['twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
function toWords(s) {
s = s.toString();
s = s.replace(/[\, ]/g,'');
if (s != parseFloat(s)) return 'not a number';
var x = s.indexOf('.');
if (x == -1)
x = s.length;
if (x > 15)
return 'too big';
var n = s.split('');
var str = '';
var sk = 0;
for (var i=0; i < x; i++) {
if ((x-i)%3==2) {
if (n[i] == '1') {
str += tn[Number(n[i+1])] + ' ';
i++;
sk=1;
} else if (n[i]!=0) {
str += tw[n[i]-2] + ' ';
sk=1;
}
} else if (n[i]!=0) { // 0235
str += dg[n[i]] +' ';
if ((x-i)%3==0) str += 'hundred ';
sk=1;
}
if ((x-i)%3==1) {
if (sk)
str += th[(x-i-1)/3] + ' ';
sk=0;
}
}
if (x != s.length) {
var y = s.length;
str += 'point ';
for (var i=x+1; i<y; i++)
str += dg[n[i]] +' ';
}
return str.replace(/\s+/g,' ');
}
Also, the above code converts to the English numbering system like Million/Billion, I need the South Asian numbering system, like in Lakhs and Crores.
Update: Looks like this is more useful than I thought. I've just published this on npm. https://www.npmjs.com/package/num-words
Here's a shorter code. with one RegEx and no loops. converts as you wanted, in south asian numbering system
var a = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
var b = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
function inWords (num) {
if ((num = num.toString()).length > 9) return 'overflow';
n = ('000000000' + num).substr(-9).match(/^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/);
if (!n) return; var str = '';
str += (n[1] != 0) ? (a[Number(n[1])] || b[n[1][0]] + ' ' + a[n[1][1]]) + 'crore ' : '';
str += (n[2] != 0) ? (a[Number(n[2])] || b[n[2][0]] + ' ' + a[n[2][1]]) + 'lakh ' : '';
str += (n[3] != 0) ? (a[Number(n[3])] || b[n[3][0]] + ' ' + a[n[3][1]]) + 'thousand ' : '';
str += (n[4] != 0) ? (a[Number(n[4])] || b[n[4][0]] + ' ' + a[n[4][1]]) + 'hundred ' : '';
str += (n[5] != 0) ? ((str != '') ? 'and ' : '') + (a[Number(n[5])] || b[n[5][0]] + ' ' + a[n[5][1]]) + 'only ' : '';
return str;
}
document.getElementById('number').onkeyup = function () {
document.getElementById('words').innerHTML = inWords(document.getElementById('number').value);
};
<span id="words"></span>
<input id="number" type="text" />
The only limitation is, you can convert maximum of 9 digits, which I think is more than sufficient in most cases..
"Deceptively simple task." – Potatoswatter
Indeed. There's many little devils hanging out in the details of this problem. It was very fun to solve tho.
EDIT: This update takes a much more compositional approach. Previously there was one big function which wrapped a couple other proprietary functions. Instead, this time we define generic reusable functions which could be used for many varieties of tasks. More about those after we take a look at numToWords itself …
// numToWords :: (Number a, String a) => a -> String
let numToWords = n => {
let a = [
'', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
];
let b = [
'', '', 'twenty', 'thirty', 'forty',
'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
];
let g = [
'', 'thousand', 'million', 'billion', 'trillion', 'quadrillion',
'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion'
];
// this part is really nasty still
// it might edit this again later to show how Monoids could fix this up
let makeGroup = ([ones,tens,huns]) => {
return [
num(huns) === 0 ? '' : a[huns] + ' hundred ',
num(ones) === 0 ? b[tens] : b[tens] && b[tens] + '-' || '',
a[tens+ones] || a[ones]
].join('');
};
// "thousands" constructor; no real good names for this, i guess
let thousand = (group,i) => group === '' ? group : `${group} ${g[i]}`;
// execute !
if (typeof n === 'number') return numToWords(String(n));
if (n === '0') return 'zero';
return comp (chunk(3)) (reverse) (arr(n))
.map(makeGroup)
.map(thousand)
.filter(comp(not)(isEmpty))
.reverse()
.join(' ');
};
Here are the dependencies:
You'll notice these require next to no documentation because their intents are immediately clear. chunk might be the only one that takes a moment to digest, but it's really not too bad. Plus the function name gives us a pretty good indication what it does, and it's probably a function we've encountered before.
const arr = x => Array.from(x);
const num = x => Number(x) || 0;
const str = x => String(x);
const isEmpty = xs => xs.length === 0;
const take = n => xs => xs.slice(0,n);
const drop = n => xs => xs.slice(n);
const reverse = xs => xs.slice(0).reverse();
const comp = f => g => x => f (g (x));
const not = x => !x;
const chunk = n => xs =>
isEmpty(xs) ? [] : [take(n)(xs), ...chunk (n) (drop (n) (xs))];
"So these make it better?"
Look at how the code has cleaned up significantly
// NEW CODE (truncated)
return comp (chunk(3)) (reverse) (arr(n))
.map(makeGroup)
.map(thousand)
.filter(comp(not)(isEmpty))
.reverse()
.join(' ');
// OLD CODE (truncated)
let grp = n => ('000' + n).substr(-3);
let rem = n => n.substr(0, n.length - 3);
let cons = xs => x => g => x ? [x, g && ' ' + g || '', ' ', xs].join('') : xs;
let iter = str => i => x => r => {
if (x === '000' && r.length === 0) return str;
return iter(cons(str)(fmt(x))(g[i]))
(i+1)
(grp(r))
(rem(r));
};
return iter('')(0)(grp(String(n)))(rem(String(n)));
Most importantly, the utility functions we added in the new code can be used other places in your app. This means that, as a side effect of implementing numToWords in this way, we get the other functions for free. Bonus soda !
Some tests
console.log(numToWords(11009));
//=> eleven thousand nine
console.log(numToWords(10000001));
//=> ten million one
console.log(numToWords(987));
//=> nine hundred eighty-seven
console.log(numToWords(1015));
//=> one thousand fifteen
console.log(numToWords(55111222333));
//=> fifty-five billion one hundred eleven million two hundred
// twenty-two thousand three hundred thirty-three
console.log(numToWords("999999999999999999999991"));
//=> nine hundred ninety-nine sextillion nine hundred ninety-nine
// quintillion nine hundred ninety-nine quadrillion nine hundred
// ninety-nine trillion nine hundred ninety-nine billion nine
// hundred ninety-nine million nine hundred ninety-nine thousand
// nine hundred ninety-one
console.log(numToWords(6000753512));
//=> six billion seven hundred fifty-three thousand five hundred
// twelve
Runnable demo
const arr = x => Array.from(x);
const num = x => Number(x) || 0;
const str = x => String(x);
const isEmpty = xs => xs.length === 0;
const take = n => xs => xs.slice(0,n);
const drop = n => xs => xs.slice(n);
const reverse = xs => xs.slice(0).reverse();
const comp = f => g => x => f (g (x));
const not = x => !x;
const chunk = n => xs =>
isEmpty(xs) ? [] : [take(n)(xs), ...chunk (n) (drop (n) (xs))];
// numToWords :: (Number a, String a) => a -> String
let numToWords = n => {
let a = [
'', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
];
let b = [
'', '', 'twenty', 'thirty', 'forty',
'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
];
let g = [
'', 'thousand', 'million', 'billion', 'trillion', 'quadrillion',
'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion'
];
// this part is really nasty still
// it might edit this again later to show how Monoids could fix this up
let makeGroup = ([ones,tens,huns]) => {
return [
num(huns) === 0 ? '' : a[huns] + ' hundred ',
num(ones) === 0 ? b[tens] : b[tens] && b[tens] + '-' || '',
a[tens+ones] || a[ones]
].join('');
};
let thousand = (group,i) => group === '' ? group : `${group} ${g[i]}`;
if (typeof n === 'number')
return numToWords(String(n));
else if (n === '0')
return 'zero';
else
return comp (chunk(3)) (reverse) (arr(n))
.map(makeGroup)
.map(thousand)
.filter(comp(not)(isEmpty))
.reverse()
.join(' ');
};
console.log(numToWords(11009));
//=> eleven thousand nine
console.log(numToWords(10000001));
//=> ten million one
console.log(numToWords(987));
//=> nine hundred eighty-seven
console.log(numToWords(1015));
//=> one thousand fifteen
console.log(numToWords(55111222333));
//=> fifty-five billion one hundred eleven million two hundred
// twenty-two thousand three hundred thirty-three
console.log(numToWords("999999999999999999999991"));
//=> nine hundred ninety-nine sextillion nine hundred ninety-nine
// quintillion nine hundred ninety-nine quadrillion nine hundred
// ninety-nine trillion nine hundred ninety-nine billion nine
// hundred ninety-nine million nine hundred ninety-nine thousand
// nine hundred ninety-one
console.log(numToWords(6000753512));
//=> six billion seven hundred fifty-three thousand five hundred
// twelve
You can transpile the code using babel.js if you want to see the ES5 variant
I spent a while developing a better solution to this. It can handle very big numbers but once they get over 16 digits you have pass the number in as a string. Something about the limit of JavaScript numbers.
function numberToEnglish( n ) {
var string = n.toString(), units, tens, scales, start, end, chunks, chunksLen, chunk, ints, i, word, words, and = 'and';
/* Remove spaces and commas */
string = string.replace(/[, ]/g,"");
/* Is number zero? */
if( parseInt( string ) === 0 ) {
return 'zero';
}
/* Array of units as words */
units = [ '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' ];
/* Array of tens as words */
tens = [ '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety' ];
/* Array of scales as words */
scales = [ '', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quatttuor-decillion', 'quindecillion', 'sexdecillion', 'septen-decillion', 'octodecillion', 'novemdecillion', 'vigintillion', 'centillion' ];
/* Split user argument into 3 digit chunks from right to left */
start = string.length;
chunks = [];
while( start > 0 ) {
end = start;
chunks.push( string.slice( ( start = Math.max( 0, start - 3 ) ), end ) );
}
/* Check if function has enough scale words to be able to stringify the user argument */
chunksLen = chunks.length;
if( chunksLen > scales.length ) {
return '';
}
/* Stringify each integer in each chunk */
words = [];
for( i = 0; i < chunksLen; i++ ) {
chunk = parseInt( chunks[i] );
if( chunk ) {
/* Split chunk into array of individual integers */
ints = chunks[i].split( '' ).reverse().map( parseFloat );
/* If tens integer is 1, i.e. 10, then add 10 to units integer */
if( ints[1] === 1 ) {
ints[0] += 10;
}
/* Add scale word if chunk is not zero and array item exists */
if( ( word = scales[i] ) ) {
words.push( word );
}
/* Add unit word if array item exists */
if( ( word = units[ ints[0] ] ) ) {
words.push( word );
}
/* Add tens word if array item exists */
if( ( word = tens[ ints[1] ] ) ) {
words.push( word );
}
/* Add 'and' string after units or tens integer if: */
if( ints[0] || ints[1] ) {
/* Chunk has a hundreds integer or chunk is the first of multiple chunks */
if( ints[2] || ! i && chunksLen ) {
words.push( and );
}
}
/* Add hundreds word if array item exists */
if( ( word = units[ ints[2] ] ) ) {
words.push( word + ' hundred' );
}
}
}
return words.reverse().join( ' ' );
}
// - - - - - Tests - - - - - -
function test(v) {
var sep = ('string'==typeof v)?'"':'';
console.log("numberToEnglish("+sep + v.toString() + sep+") = "+numberToEnglish(v));
}
test(2);
test(721);
test(13463);
test(1000001);
test("21,683,200,000,621,384");
You might want to try it recursive. It works for numbers between 0 and 999999. Keep in mind that (~~) does the same as Math.floor
var num = "zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen".split(" ");
var tens = "twenty thirty forty fifty sixty seventy eighty ninety".split(" ");
function number2words(n){
if (n < 20) return num[n];
var digit = n%10;
if (n < 100) return tens[~~(n/10)-2] + (digit? "-" + num[digit]: "");
if (n < 1000) return num[~~(n/100)] +" hundred" + (n%100 == 0? "": " " + number2words(n%100));
return number2words(~~(n/1000)) + " thousand" + (n%1000 != 0? " " + number2words(n%1000): "");
}
I like the result I got here which i think is easy to read and short enough to fit as a solution.
function NumInWords (number) {
const first = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
const tens = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
const mad = ['', 'thousand', 'million', 'billion', 'trillion'];
let word = '';
for (let i = 0; i < mad.length; i++) {
let tempNumber = number%(100*Math.pow(1000,i));
if (Math.floor(tempNumber/Math.pow(1000,i)) !== 0) {
if (Math.floor(tempNumber/Math.pow(1000,i)) < 20) {
word = first[Math.floor(tempNumber/Math.pow(1000,i))] + mad[i] + ' ' + word;
} else {
word = tens[Math.floor(tempNumber/(10*Math.pow(1000,i)))] + '-' + first[Math.floor(tempNumber/Math.pow(1000,i))%10] + mad[i] + ' ' + word;
}
}
tempNumber = number%(Math.pow(1000,i+1));
if (Math.floor(tempNumber/(100*Math.pow(1000,i))) !== 0) word = first[Math.floor(tempNumber/(100*Math.pow(1000,i)))] + 'hunderd ' + word;
}
return word;
}
console.log(NumInWords(89754697976431))
And the result is :
eighty-nine trillion seven hundred fifty-four billion six hundred ninety-seven million nine hundred seventy-six thousand four hundred thirty-one
<html>
<head>
<title>HTML - Convert numbers to words using JavaScript</title>
<script type="text/javascript">
function onlyNumbers(evt) {
var e = event || evt; // For trans-browser compatibility
var charCode = e.which || e.keyCode;
if (charCode > 31 && (charCode < 48 || charCode > 57))
return false;
return true;
}
function NumToWord(inputNumber, outputControl) {
var str = new String(inputNumber)
var splt = str.split("");
var rev = splt.reverse();
var once = ['Zero', ' One', ' Two', ' Three', ' Four', ' Five', ' Six', ' Seven', ' Eight', ' Nine'];
var twos = ['Ten', ' Eleven', ' Twelve', ' Thirteen', ' Fourteen', ' Fifteen', ' Sixteen', ' Seventeen', ' Eighteen', ' Nineteen'];
var tens = ['', 'Ten', ' Twenty', ' Thirty', ' Forty', ' Fifty', ' Sixty', ' Seventy', ' Eighty', ' Ninety'];
numLength = rev.length;
var word = new Array();
var j = 0;
for (i = 0; i < numLength; i++) {
switch (i) {
case 0:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = '' + once[rev[i]];
}
word[j] = word[j];
break;
case 1:
aboveTens();
break;
case 2:
if (rev[i] == 0) {
word[j] = '';
}
else if ((rev[i - 1] == 0) || (rev[i - 2] == 0)) {
word[j] = once[rev[i]] + " Hundred ";
}
else {
word[j] = once[rev[i]] + " Hundred and";
}
break;
case 3:
if (rev[i] == 0 || rev[i + 1] == 1) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if ((rev[i + 1] != 0) || (rev[i] > 0)) {
word[j] = word[j] + " Thousand";
}
break;
case 4:
aboveTens();
break;
case 5:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if (rev[i + 1] !== '0' || rev[i] > '0') {
word[j] = word[j] + " Lakh";
}
break;
case 6:
aboveTens();
break;
case 7:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if (rev[i + 1] !== '0' || rev[i] > '0') {
word[j] = word[j] + " Crore";
}
break;
case 8:
aboveTens();
break;
// This is optional.
// case 9:
// if ((rev[i] == 0) || (rev[i + 1] == 1)) {
// word[j] = '';
// }
// else {
// word[j] = once[rev[i]];
// }
// if (rev[i + 1] !== '0' || rev[i] > '0') {
// word[j] = word[j] + " Arab";
// }
// break;
// case 10:
// aboveTens();
// break;
default: break;
}
j++;
}
function aboveTens() {
if (rev[i] == 0) { word[j] = ''; }
else if (rev[i] == 1) { word[j] = twos[rev[i - 1]]; }
else { word[j] = tens[rev[i]]; }
}
word.reverse();
var finalOutput = '';
for (i = 0; i < numLength; i++) {
finalOutput = finalOutput + word[i];
}
document.getElementById(outputControl).innerHTML = finalOutput;
}
</script>
</head>
<body>
<h1>
HTML - Convert numbers to words using JavaScript</h1>
<input id="Text1" type="text" onkeypress="return onlyNumbers(this.value);" onkeyup="NumToWord(this.value,'divDisplayWords');"
maxlength="9" style="background-color: #efefef; border: 2px solid #CCCCC; font-size: large" />
<br />
<br />
<div id="divDisplayWords" style="font-size: 13; color: Teal; font-family: Arial;">
</div>
</body>
</html>
I modified MC Shaman's code to fix the bug of single number having and appear before it
function numberToEnglish( n ) {
var string = n.toString(), units, tens, scales, start, end, chunks, chunksLen, chunk, ints, i, word, words, and = 'and';
/* Remove spaces and commas */
string = string.replace(/[, ]/g,"");
/* Is number zero? */
if( parseInt( string ) === 0 ) {
return 'zero';
}
/* Array of units as words */
units = [ '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' ];
/* Array of tens as words */
tens = [ '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety' ];
/* Array of scales as words */
scales = [ '', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quatttuor-decillion', 'quindecillion', 'sexdecillion', 'septen-decillion', 'octodecillion', 'novemdecillion', 'vigintillion', 'centillion' ];
/* Split user argument into 3 digit chunks from right to left */
start = string.length;
chunks = [];
while( start > 0 ) {
end = start;
chunks.push( string.slice( ( start = Math.max( 0, start - 3 ) ), end ) );
}
/* Check if function has enough scale words to be able to stringify the user argument */
chunksLen = chunks.length;
if( chunksLen > scales.length ) {
return '';
}
/* Stringify each integer in each chunk */
words = [];
for( i = 0; i < chunksLen; i++ ) {
chunk = parseInt( chunks[i] );
if( chunk ) {
/* Split chunk into array of individual integers */
ints = chunks[i].split( '' ).reverse().map( parseFloat );
/* If tens integer is 1, i.e. 10, then add 10 to units integer */
if( ints[1] === 1 ) {
ints[0] += 10;
}
/* Add scale word if chunk is not zero and array item exists */
if( ( word = scales[i] ) ) {
words.push( word );
}
/* Add unit word if array item exists */
if( ( word = units[ ints[0] ] ) ) {
words.push( word );
}
/* Add tens word if array item exists */
if( ( word = tens[ ints[1] ] ) ) {
words.push( word );
}
/* Add 'and' string after units or tens integer if: */
if( ints[0] || ints[1] ) {
/* Chunk has a hundreds integer or chunk is the first of multiple chunks */
if( ints[2] || (i + 1) > chunksLen ) {
words.push( and );
}
}
/* Add hundreds word if array item exists */
if( ( word = units[ ints[2] ] ) ) {
words.push( word + ' hundred' );
}
}
}
return words.reverse().join( ' ' );
}
// - - - - - Tests - - - - - -
function figure(val) {
finalFig = numberToEnglish(val);
document.getElementById("words").innerHTML = finalFig;
}
<span id="words"></span>
<input id="number" type="text" onkeyup=figure(this.value) />
Update February 2021
Although this question is raised over 8 years ago with various solutions and answers, the easiest solution that can be easily updated to increase the scale by just inserting a name in the array without code modification; and also using very short code is the function below.
This solution is for the English reading of numbers (not the South-Asian System) and uses the standard US English (American way) of writing large numbers. i.e. it does not use the UK System (the UK system uses the word "and" like: "three hundred and twenty-two thousand").
Test cases are provided and also an input field.
Remember, it is "Unsigned Integers" that we are converting to words.
You can increase the scale[] array beyond Sextillion.
As the function is short, you can use it as an internal function in, say, currency conversion where decimal numbers are used and call it twice for the whole part and the fractional part.
Hope it is useful.
/********************************************************
* #function : integerToWords()
* #purpose : Converts Unsigned Integers to Words
* Using String Triplet Array.
* #version : 1.05
* #author : Mohsen Alyafei
* #date : 15 January 2021
* #param : {number} [integer numeric or string]
* #returns : {string} The wordified number string
********************************************************/
const 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","Hundred"],
Scale = ["","Thousand","Million","Billion","Trillion","Quadrillion","Quintillion","Sextillion"];
//==================================
const integerToWords = (n = 0) => {
if (n == 0) return "Zero"; // check for zero
n = ("0".repeat(2*(n+="").length % 3) + n).match(/.{3}/g); // create triplets array
if (n.length > Scale.length) return "Too Large"; // check if larger than scale array
let out= ""; return n.forEach((Triplet,pos) => { // loop into array for each triplet
if (+Triplet) { out+=' ' +(+Triplet[0] ? Ones[+Triplet[0]]+' '+ Tens[10] : "") +
' ' + (+Triplet.substr(1)< 20 ? Ones[+Triplet.substr(1)] :
Tens[+Triplet[1]] + (+Triplet[2] ? "-" : "") + Ones[+Triplet[2]]) +
' ' + Scale[n.length-pos-1]; }
}),out.replace(/\s+/g,' ').trim();}; // lazy job using trim()
//==================================
//=========================================
// Test Cases
//=========================================
var r=0; // test tracker
r |= test(0,"Zero");
r |= test(5,"Five");
r |= test(10,"Ten");
r |= test(19,"Nineteen");
r |= test(33,"Thirty-Three");
r |= test(100,"One Hundred");
r |= test(111,"One Hundred Eleven");
r |= test(890,"Eight Hundred Ninety");
r |= test(1234,"One Thousand Two Hundred Thirty-Four");
r |= test(12345,"Twelve Thousand Three Hundred Forty-Five");
r |= test(123456,"One Hundred Twenty-Three Thousand Four Hundred Fifty-Six");
r |= test(1234567,"One Million Two Hundred Thirty-Four Thousand Five Hundred Sixty-Seven");
r |= test(12345678,"Twelve Million Three Hundred Forty-Five Thousand Six Hundred Seventy-Eight");
r |= test(123456789,"One Hundred Twenty-Three Million Four Hundred Fifty-Six Thousand Seven Hundred Eighty-Nine");
r |= test(1234567890,"One Billion Two Hundred Thirty-Four Million Five Hundred Sixty-Seven Thousand Eight Hundred Ninety");
r |= test(1001,"One Thousand One");
r |= test(10001,"Ten Thousand One");
r |= test(100001,"One Hundred Thousand One");
r |= test(1000001,"One Million One");
r |= test(10000001,"Ten Million One");
r |= test(100000001,"One Hundred Million One");
r |= test(12012,"Twelve Thousand Twelve");
r |= test(120012,"One Hundred Twenty Thousand Twelve");
r |= test(1200012,"One Million Two Hundred Thousand Twelve");
r |= test(12000012,"Twelve Million Twelve");
r |= test(120000012,"One Hundred Twenty Million Twelve");
r |= test(75075,"Seventy-Five Thousand Seventy-Five");
r |= test(750075,"Seven Hundred Fifty Thousand Seventy-Five");
r |= test(7500075,"Seven Million Five Hundred Thousand Seventy-Five");
r |= test(75000075,"Seventy-Five Million Seventy-Five");
r |= test(750000075,"Seven Hundred Fifty Million Seventy-Five");
r |= test(1000,"One Thousand");
r |= test(1000000,"One Million");
r |= test(1000000000,"One Billion");
r |= test(1000000000000,"One Trillion");
r |= test("1000000000000000","One Quadrillion");
r |= test("1000000000000000000","One Quintillion");
r |= test("1000000100100100100","One Quintillion One Hundred Billion One Hundred Million One Hundred Thousand One Hundred");
if (r==0) console.log("All Tests Passed.");
//=====================================
// Tester Function
//=====================================
function test(n,should) {
let result = integerToWords(n);
if (result !== should) {console.log(`${n} Output : ${result}\n${n} Should be: ${should}`);return 1;}
}
<input type="text" name="number" placeholder="Please enter an Integer Number" onkeyup="word.innerHTML=integerToWords(this.value)" />
<div id="word"></div>
TypeScript Version Based on ES2022 + Fastest
Test on Typescript Playground
Hindi Version
class N2WHindi {
private static readonly zeroTo99: string[] =
'|एक|दो|तीन|चार|पाँच|छः|सात|आठ|नौ|दश|ग्यारह|बारह|तेरह|चौदह|पन्द्रह|सोलह|सत्रह|अठारह|उन्नीस|बीस|इक्कीस|बाईस|तेईस|चौबीस|पच्चीस|छब्बीस|सत्ताईस|अट्ठाईस|उनतीस|तीस|इकतीस|बत्तीस|तैंतीस|चौंतीस|पैंतीस|छत्तीस|सैंतीस|अड़तीस|उनतालीस|चालीस|इकतालीस|बयालीस|तैंतालीस|चौवालीस|पैंतालीस|छियालीस|सैंतालीस|अड़तालीस|उनचास|पचास|इक्यावन|बावन|तिरपन|चौवन|पचपन|छप्पन|सत्तावन|अट्ठावन|उनसठ|साठ|इकसठ|बासठ|तिरसठ|चौंसठ|पैंसठ|छियासठ|सड़सठ|अड़सठ|उनहत्तर|सत्तर|इकहत्तर|बहत्तर|तिहत्तर|चौहत्तर|पचहत्तर|छिहत्तर|सतहत्तर|अठहत्तर|उन्यासी|अस्सी|इक्यासी|बयासी|तिरासी|चौरासी|पचासी|छियासी|सत्तासी|अट्ठासी|नवासी|नब्बे|इक्यानबे|बानबे|तिरानबे|चौरानबे|पंचानबे|छियानबे|सत्तानबे|अट्ठानबे|निन्यान्बे'.split(
'|'
);
private static readonly place: string[] = 'हज़ार|लाख|करोड़|अरब|खरब|नील'.split('|');
public static convert(x: string): string {
let n: number = x.length;
x = n === 0 ? '00' : n === 1 || n % 2 === 0 ? '0' + x : x;
n = x.length;
let r: string = N2WHindi.zeroTo99[x.charCodeAt((n -= 2)) * 10 + x.charCodeAt(n + 1) - 528];
if (n > 0) {
const v: string = N2WHindi.zeroTo99[x.charCodeAt((n -= 1)) - 48];
if (v) r = v + ' सौ' + (r ? ' ' + r : '');
}
for (let i = 0; n > 0; i++) {
const v: string = N2WHindi.zeroTo99[x.charCodeAt((n -= 2)) * 10 + x.charCodeAt(n + 1) - 528];
if (v) r = v + ' ' + N2WHindi.place[i] + (r ? ' ' + r : '');
}
return r || 'शून्य';
}
}
Indian English Version
class N2WIndian {
private static readonly zeroTo99: string[] = [];
private static readonly place: string[] = 'Thousand|Lakh|Crore|Arab|Kharab|Nil'.split('|');
static {
const ones: string[] =
'|One|Two|Three|Four|Five|Six|Seven|Eight|Nine|Ten|Eleven|Twelve|Thirteen|Fourteen|Fifteen|Sixteen|Seventeen|Eighteen|Nineteen'.split(
'|'
);
const tens: string[] = '||Twenty|Thirty|Forty|Fifty|Sixty|Seventy|Eighty|Ninety'.split('|');
for (let i = 0; i < 100; i++) {
const t: number = Math.floor(i / 10);
const o: number = i % 10;
N2WIndian.zeroTo99.push(t < 2 ? ones[i] : tens[t] + (o ? ' ' + ones[o] : ''));
}
}
public static convert(x: string): string {
let n: number = x.length;
x = n === 0 ? '00' : n === 1 || n % 2 === 0 ? '0' + x : x;
n = x.length;
let r = N2WIndian.zeroTo99[x.charCodeAt((n -= 2)) * 10 + x.charCodeAt(n + 1) - 528];
if (n >= 1) {
const v: string = N2WIndian.zeroTo99[x.charCodeAt((n -= 1)) - 48];
if (v) r = v + ' Hundred' + (r ? ' ' + r : '');
}
for (let i = 0; n > 0; i++) {
const v: string = N2WIndian.zeroTo99[x.charCodeAt((n -= 2)) * 10 + x.charCodeAt(n + 1) - 528];
if (v) r = v + ' ' + N2WIndian.place[i] + (r ? ' ' + r : '');
}
return r || 'Zero';
}
}
International Version
class N2WIntl {
private static readonly zeroTo999: string[] = [];
private static readonly place =
'|Thousand|Million|Billion|Trillion|Quadrillion|Quintillion|Sextillion|Septillion|Octillion|Nonillion|Decillion|Undecillion|Duodecillion|Tredecillion|Quattuordecillion|Quindecillion|Sedecillion|Septendecillion|Octodecillion|Novendecillion|Vigintillion|Unvigintillion|Duovigintillion|Tresvigintillion|Quattuorvigintillion|Quinvigintillion|Sesvigintillion|Septemvigintillion|Octovigintillion|Novemvigintillion|Trigintillion|Untrigintillion|Duotrigintillion|Trestrigintillion|Quattuortrigintillion|Quintrigintillion|Sestrigintillion|Septentrigintillion|Octotrigintillion|Noventrigintillion|Quadragintillion'.split(
'|'
);
static {
const ones =
'|One|Two|Three|Four|Five|Six|Seven|Eight|Nine|Ten|Eleven|Twelve|Thirteen|Fourteen|Fifteen|Sixteen|Seventeen|Eighteen|Nineteen'.split(
'|'
);
const tens = '||Twenty|Thirty|Forty|Fifty|Sixty|Seventy|Eighty|Ninety'.split('|');
for (let i = 0; i < 100; i++) {
const t = Math.floor(i / 10);
const o = i % 10;
N2WIntl.zeroTo999[i] = t < 2 ? ones[i] : tens[t] + (o === 0 ? '' : ' ' + ones[o]);
}
for (let i = 100; i < 1000; i++) {
const h = Math.floor(i / 100);
const t = Math.floor(i / 10) % 10;
const o = i % 10;
const r = N2WIntl.zeroTo999[h] + ' Hundred';
N2WIntl.zeroTo999[i] = t === 0 && o === 0 ? r : r + ' ' + N2WIntl.zeroTo999[t * 10 + o];
}
}
public static convert(x: string): string {
let n = x.length;
x = n === 0 ? '000' : (n % 3 === 1 ? '00' : n % 3 === 2 ? '0' : '') + x;
n = x.length;
let r = '';
for (let i = 0; n > 0; i++) {
const v: string =
N2WIntl.zeroTo999[
x.charCodeAt((n -= 3)) * 100 + x.charCodeAt(n + 1) * 10 + x.charCodeAt(n + 2) - 5328
];
if (v) r = v + (i ? ' ' + N2WIntl.place[i] : '') + (r ? ' ' + r : '');
}
return r || 'Zero';
}
}
const test = () => {
{
let n = 5000000;
const test: string = '1234567890';
const t0 = performance.now();
while (n-- > 0) {
N2WHindi.convert(test);
}
const t1 = performance.now();
console.log('1234567890 to 5 Million times: ' + (t1 - t0) + 'ms');
console.log('10^15 -1 :\n' + '9'.repeat(15) + '\n' + N2WHindi.convert('9'.repeat(15)));
}
{
let n = 5000000;
const test: string = '1234567890';
const t0 = performance.now();
while (n-- > 0) {
N2WIndian.convert(test);
}
const t1 = performance.now();
console.log('1234567890 to 5 Million times: ' + (t1 - t0) + 'ms');
console.log('10^15 -1 :\n' + '9'.repeat(15) + '\n' + N2WIndian.convert('9'.repeat(15)));
}
{
let n = 5000000;
const test: string = '1234567890';
const t0 = performance.now();
while (n-- > 0) {
N2WIntl.convert(test);
}
const t1 = performance.now();
console.log('1234567890 to 5 Million times: ' + (t1 - t0) + 'ms');
console.log('10^126 -1 :\n' + '9'.repeat(126) + '\n' + N2WIntl.convert('9'.repeat(126)));
}
};
test();
Example
N2WHindi.convert('122356')
'एक लाख बाईस हज़ार तीन सौ छप्पन'
N2WIndian.convert('122356')
'One Lakh Twenty Two Thousand Three Hundred Fifty Six'
N2WIntl.convert('122356')
'One Hundred Twenty Two Thousand Three Hundred Fifty Six'
Example to convert currency
const [r, p] = "23.54".split('.');
`${N2WHindi.convert(r)} रुपया और ${N2WHindi.convert(p)} पैसा`
'तेईस रुपया और चौवन पैसा'
`${N2WIndian.convert(r)} Rupees and ${N2WIndian.convert(p)} Paisa`
'Twenty Three Rupees and Fifty Four Paisa'
`${N2WIntl.convert(r)} Dollars and ${N2WIntl.convert(p)} Cents`
'Twenty Three Dollars and Fifty Four Cents'
Converting the input string into a number rather than keeping it as a string, limits the solution to the maximum allowed float / integer value on that machine/browser. My script below handles currency up to 1 Trillion dollars - 1 cent :-). I can be extended to handle up to 999 Trillions by adding 3 or 4 lines of code.
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"];
function words999(n999) { // n999 is an integer less than or equal to 999.
//
// Accept any 3 digit int incl 000 & 999 and return words.
//
var words = ''; var Hn = 0; var n99 = 0;
Hn = Math.floor(n999 / 100); // # of hundreds in it
if (Hn > 0) { // if at least one 100
words = words99(Hn) + " Hundred"; // one call for hundreds
}
n99 = n999 - (Hn * 100); // subtract the hundreds.
words += ((words == '')?'':' ') + words99(n99); // combine the hundreds with tens & ones.
return words;
} // function words999( n999 )
function words99(n99) { // n99 is an integer less than or equal to 99.
//
// Accept any 2 digit int incl 00 & 99 and return words.
//
var words = ''; var Dn = 0; var Un = 0;
Dn = Math.floor(n99 / 10); // # of tens
Un = n99 % 10; // units
if (Dn > 0 || Un > 0) {
if (Dn < 2) {
words += ones[Dn * 10 + Un]; // words for a # < 20
} else {
words += tens[Dn];
if (Un > 0) words += "-" + ones[Un];
}
} // if ( Dn > 0 || Un > 0 )
return words;
} // function words99( n99 )
function getAmtInWords(id1, id2) { // use numeric value of id1 to populate text in id2
//
// Read numeric amount field and convert into word amount
//
var t1 = document.getElementById(id1).value;
var t2 = t1.trim();
amtStr = t2.replace(/,/g,''); // $123,456,789.12 = 123456789.12
dotPos = amtStr.indexOf('.'); // position of dot before cents, -ve if it doesn't exist.
if (dotPos > 0) {
dollars = amtStr.slice(0,dotPos); // 1234.56 = 1234
cents = amtStr.slice(dotPos+1); // 1234.56 = .56
} else if (dotPos == 0) {
dollars = '0';
cents = amtStr.slice(dotPos+1); // 1234.56 = .56
} else {
dollars = amtStr.slice(0); // 1234 = 1234
cents = '0';
}
t1 = '000000000000' + dollars; // to extend to trillion, use 15 zeros
dollars = t1.slice(-12); // and -15 here.
billions = Number(dollars.substr(0,3));
millions = Number(dollars.substr(3,3));
thousands = Number(dollars.substr(6,3));
hundreds = Number(dollars.substr(9,3));
t1 = words999(billions); bW = t1.trim(); // Billions in words
t1 = words999(millions); mW = t1.trim(); // Millions in words
t1 = words999(thousands); tW = t1.trim(); // Thousands in words
t1 = words999(hundreds); hW = t1.trim(); // Hundreds in words
t1 = words99(cents); cW = t1.trim(); // Cents in words
var totAmt = '';
if (bW != '') totAmt += ((totAmt != '') ? ' ' : '') + bW + ' Billion';
if (mW != '') totAmt += ((totAmt != '') ? ' ' : '') + mW + ' Million';
if (tW != '') totAmt += ((totAmt != '') ? ' ' : '') + tW + ' Thousand';
if (hW != '') totAmt += ((totAmt != '') ? ' ' : '') + hW + ' Dollars';
if (cW != '') totAmt += ((totAmt != '') ? ' and ' : '') + cW + ' Cents';
// alert('totAmt = ' + totAmt); // display words in a alert
t1 = document.getElementById(id2).value;
t2 = t1.trim();
if (t2 == '') document.getElementById(id2).value = totAmt;
return false;
} // function getAmtInWords( id1, id2 )
// ======================== [ End Code ] ====================================
If you need with Cent then you may use this one
<script>
var iWords = ['zero', ' one', ' two', ' three', ' four', ' five', ' six', ' seven', ' eight', ' nine'];
var ePlace = ['ten', ' eleven', ' twelve', ' thirteen', ' fourteen', ' fifteen', ' sixteen', ' seventeen', ' eighteen', ' nineteen'];
var tensPlace = ['', ' ten', ' twenty', ' thirty', ' forty', ' fifty', ' sixty', ' seventy', ' eighty', ' ninety'];
var inWords = [];
var numReversed, inWords, actnumber, i, j;
function tensComplication() {
if (actnumber[i] == 0) {
inWords[j] = '';
} else if (actnumber[i] == 1) {
inWords[j] = ePlace[actnumber[i - 1]];
} else {
inWords[j] = tensPlace[actnumber[i]];
}
}
function convertAmount() {
var numericValue = document.getElementById('bdt').value;
numericValue = parseFloat(numericValue).toFixed(2);
var amount = numericValue.toString().split('.');
var taka = amount[0];
var paisa = amount[1];
document.getElementById('container').innerHTML = convert(taka) +" taka and "+ convert(paisa)+" paisa only";
}
function convert(numericValue) {
inWords = []
if(numericValue == "00" || numericValue =="0"){
return 'zero';
}
var obStr = numericValue.toString();
numReversed = obStr.split('');
actnumber = numReversed.reverse();
if (Number(numericValue) == 0) {
document.getElementById('container').innerHTML = 'BDT Zero';
return false;
}
var iWordsLength = numReversed.length;
var finalWord = '';
j = 0;
for (i = 0; i < iWordsLength; i++) {
switch (i) {
case 0:
if (actnumber[i] == '0' || actnumber[i + 1] == '1') {
inWords[j] = '';
} else {
inWords[j] = iWords[actnumber[i]];
}
inWords[j] = inWords[j] + '';
break;
case 1:
tensComplication();
break;
case 2:
if (actnumber[i] == '0') {
inWords[j] = '';
} else if (actnumber[i - 1] !== '0' && actnumber[i - 2] !== '0') {
inWords[j] = iWords[actnumber[i]] + ' hundred';
} else {
inWords[j] = iWords[actnumber[i]] + ' hundred';
}
break;
case 3:
if (actnumber[i] == '0' || actnumber[i + 1] == '1') {
inWords[j] = '';
} else {
inWords[j] = iWords[actnumber[i]];
}
if (actnumber[i + 1] !== '0' || actnumber[i] > '0') {
inWords[j] = inWords[j] + ' thousand';
}
break;
case 4:
tensComplication();
break;
case 5:
if (actnumber[i] == '0' || actnumber[i + 1] == '1') {
inWords[j] = '';
} else {
inWords[j] = iWords[actnumber[i]];
}
if (actnumber[i + 1] !== '0' || actnumber[i] > '0') {
inWords[j] = inWords[j] + ' lakh';
}
break;
case 6:
tensComplication();
break;
case 7:
if (actnumber[i] == '0' || actnumber[i + 1] == '1') {
inWords[j] = '';
} else {
inWords[j] = iWords[actnumber[i]];
}
inWords[j] = inWords[j] + ' crore';
break;
case 8:
tensComplication();
break;
default:
break;
}
j++;
}
inWords.reverse();
for (i = 0; i < inWords.length; i++) {
finalWord += inWords[i];
}
return finalWord;
}
</script>
<input type="text" name="bdt" id="bdt" />
<input type="button" name="sr1" value="Click Here" onClick="convertAmount()"/>
<div id="container"></div>
js fiddle
Here taka mean USD and paisa mean cent
This is in response to #LordZardeck's comment to #naomik's excellent answer above. Sorry, I would've commented directly but I've never posted before so I don't have the privilege to do so, so I am posting here instead.
Anyhow, I just happened to translate the ES5 version to a more readable form this past weekend so I'm sharing it here. This should be faithful to the original (including the recent edit) and I hope the naming is clear and accurate.
function int_to_words(int) {
if (int === 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','fourty','fifty','sixty','seventy','eighty','ninety'];
var SCALE = ['','thousand','million','billion','trillion','quadrillion','quintillion','sextillion','septillion','octillion','nonillion'];
// Return string of first three digits, padded with zeros if needed
function get_first(str) {
return ('000' + str).substr(-3);
}
// Return string of digits with first three digits chopped off
function get_rest(str) {
return str.substr(0, str.length - 3);
}
// Return string of triplet convereted to words
function triplet_to_words(_3rd, _2nd, _1st) {
return (_3rd == '0' ? '' : ONES[_3rd] + ' hundred ') + (_1st == '0' ? TENS[_2nd] : TENS[_2nd] && TENS[_2nd] + '-' || '') + (ONES[_2nd + _1st] || ONES[_1st]);
}
// Add to words, triplet words with scale word
function add_to_words(words, triplet_words, scale_word) {
return triplet_words ? triplet_words + (scale_word && ' ' + scale_word || '') + ' ' + words : words;
}
function iter(words, i, first, rest) {
if (first == '000' && rest.length === 0) return words;
return iter(add_to_words(words, triplet_to_words(first[0], first[1], first[2]), SCALE[i]), ++i, get_first(rest), get_rest(rest));
}
return iter('', 0, get_first(String(int)), get_rest(String(int)));
}
var inWords = function(totalRent){
//console.log(totalRent);
var a = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
var b = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
var number = parseFloat(totalRent).toFixed(2).split(".");
var num = parseInt(number[0]);
var digit = parseInt(number[1]);
//console.log(num);
if ((num.toString()).length > 9) return 'overflow';
var n = ('000000000' + num).substr(-9).match(/^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/);
var d = ('00' + digit).substr(-2).match(/^(\d{2})$/);;
if (!n) return; var str = '';
str += (n[1] != 0) ? (a[Number(n[1])] || b[n[1][0]] + ' ' + a[n[1][1]]) + 'crore ' : '';
str += (n[2] != 0) ? (a[Number(n[2])] || b[n[2][0]] + ' ' + a[n[2][1]]) + 'lakh ' : '';
str += (n[3] != 0) ? (a[Number(n[3])] || b[n[3][0]] + ' ' + a[n[3][1]]) + 'thousand ' : '';
str += (n[4] != 0) ? (a[Number(n[4])] || b[n[4][0]] + ' ' + a[n[4][1]]) + 'hundred ' : '';
str += (n[5] != 0) ? (a[Number(n[5])] || b[n[5][0]] + ' ' + a[n[5][1]]) + 'Rupee ' : '';
str += (d[1] != 0) ? ((str != '' ) ? "and " : '') + (a[Number(d[1])] || b[d[1][0]] + ' ' + a[d[1][1]]) + 'Paise ' : 'Only!';
console.log(str);
return str;
}
This is modified code supports for Indian Rupee with 2 decimal place.
Below are the translations from
integer to word
float to word
money to word
Test cases are at the bottom
var ONE_THOUSAND = Math.pow(10, 3);
var ONE_MILLION = Math.pow(10, 6);
var ONE_BILLION = Math.pow(10, 9);
var ONE_TRILLION = Math.pow(10, 12);
var ONE_QUADRILLION = Math.pow(10, 15);
var ONE_QUINTILLION = Math.pow(10, 18);
function integerToWord(integer) {
var prefix = '';
var suffix = '';
if (!integer){ return "zero"; }
if(integer < 0){
prefix = "negative";
suffix = integerToWord(-1 * integer);
return prefix + " " + suffix;
}
if(integer <= 90){
switch (integer) {
case integer < 0:
prefix = "negative";
suffix = integerToWord(-1 * integer);
return prefix + " " + suffix;
case 1: return "one";
case 2: return "two";
case 3: return "three";
case 4: return "four";
case 5: return "five";
case 6: return "six";
case 7: return "seven";
case 8: return "eight";
case 9: return "nine";
case 10: return "ten";
case 11: return "eleven";
case 12: return "twelve";
case 13: return "thirteen";
case 14: return "fourteen";
case 15: return "fifteen";
case 16: return "sixteen";
case 17: return "seventeen";
case 18: return "eighteen";
case 19: return "nineteen";
case 20: return "twenty";
case 30: return "thirty";
case 40: return "forty";
case 50: return "fifty";
case 60: return "sixty";
case 70: return "seventy";
case 80: return "eighty";
case 90: return "ninety";
default: break;
}
}
if(integer < 100){
prefix = integerToWord(integer - integer % 10);
suffix = integerToWord(integer % 10);
return prefix + "-" + suffix;
}
if(integer < ONE_THOUSAND){
prefix = integerToWord(parseInt(Math.floor(integer / 100), 10) ) + " hundred";
if (integer % 100){ suffix = " and " + integerToWord(integer % 100); }
return prefix + suffix;
}
if(integer < ONE_MILLION){
prefix = integerToWord(parseInt(Math.floor(integer / ONE_THOUSAND), 10)) + " thousand";
if (integer % ONE_THOUSAND){ suffix = integerToWord(integer % ONE_THOUSAND); }
}
else if(integer < ONE_BILLION){
prefix = integerToWord(parseInt(Math.floor(integer / ONE_MILLION), 10)) + " million";
if (integer % ONE_MILLION){ suffix = integerToWord(integer % ONE_MILLION); }
}
else if(integer < ONE_TRILLION){
prefix = integerToWord(parseInt(Math.floor(integer / ONE_BILLION), 10)) + " billion";
if (integer % ONE_BILLION){ suffix = integerToWord(integer % ONE_BILLION); }
}
else if(integer < ONE_QUADRILLION){
prefix = integerToWord(parseInt(Math.floor(integer / ONE_TRILLION), 10)) + " trillion";
if (integer % ONE_TRILLION){ suffix = integerToWord(integer % ONE_TRILLION); }
}
else if(integer < ONE_QUINTILLION){
prefix = integerToWord(parseInt(Math.floor(integer / ONE_QUADRILLION), 10)) + " quadrillion";
if (integer % ONE_QUADRILLION){ suffix = integerToWord(integer % ONE_QUADRILLION); }
} else {
return '';
}
return prefix + " " + suffix;
}
function moneyToWord(value){
var decimalValue = (value % 1);
var integer = value - decimalValue;
decimalValue = Math.round(decimalValue * 100);
var decimalText = !decimalValue? '': integerToWord(decimalValue) + ' cent' + (decimalValue === 1? '': 's');
var integerText= !integer? '': integerToWord(integer) + ' dollar' + (integer === 1? '': 's');
return (
integer && !decimalValue? integerText:
integer && decimalValue? integerText + ' and ' + decimalText:
!integer && decimalValue? decimalText:
'zero cents'
);
}
function floatToWord(value){
var decimalValue = (value % 1);
var integer = value - decimalValue;
decimalValue = Math.round(decimalValue * 100);
var decimalText = !decimalValue? '':
decimalValue < 10? "point o' " + integerToWord(decimalValue):
decimalValue % 10 === 0? 'point ' + integerToWord(decimalValue / 10):
'point ' + integerToWord(decimalValue);
return (
integer && !decimalValue? integerToWord(integer):
integer && decimalValue? [integerToWord(integer), decimalText].join(' '):
!integer && decimalValue? decimalText:
integerToWord(0)
);
}
// test
(function(){
console.log('integerToWord ==================================');
for(var i = 0; i < 101; ++i){
console.log('%s=%s', i, integerToWord(i));
}
console.log('floatToWord ====================================');
i = 131;
while(i--){
console.log('%s=%s', i / 100, floatToWord(i / 100));
}
console.log('moneyToWord ====================================');
for(i = 0; i < 131; ++i){
console.log('%s=%s', i / 100, moneyToWord(i / 100));
}
}());
Another conversion that uses remainders and supports different languages:
function numberToWords(number) {
var result = [];
var fraction = number.toFixed(2).split('.');
var integer_part = parseInt(fraction[0]);
// var fractional_part = parseInt(fraction[1]); -- not handled here
var previousNumber = null;
for (var i = 0; i < fraction[0].length; i++) {
var reminder = Math.floor(integer_part % 10);
integer_part /= 10;
var name = getNumberName(reminder, i, fraction[0].length, previousNumber);
previousNumber = reminder;
if (name)
result.push(name);
}
result.reverse();
return result.join(' ');
}
The getNumberName function is language-dependent and handles numbers up to 9999 (but it is easy to extend it to handle larger numbers):
function getNumberName(number, power, places, previousNumber) {
var result = "";
if (power == 1) {
result = handleTeensAndTys(number, previousNumber);
} else if (power == 0 && places != 1 || number == 0) {
// skip number that was handled in teens and zero
} else {
result = locale.numberNames[number.toString()] + locale.powerNames[power.toString()];
}
return result;
}
handleTeensAndTys handles multiples of ten:
function handleTeensAndTys(number, previousNumber) {
var result = "";
if (number == 1) { // teens
if (previousNumber in locale.specialTeenNames) {
result = locale.specialTeenNames[previousNumber];
} else if (previousNumber in locale.specialTyNames) {
result = locale.specialTyNames[previousNumber] + locale.teenSuffix;
} else {
result = locale.numberNames[previousNumber] + locale.teenSuffix;
}
} else if (number == 0) { // previousNumber was not handled in teens
result = locale.numberNames[previousNumber.toString()];
} else { // other tys
if (number in locale.specialTyNames) {
result = locale.specialTyNames[number];
} else {
result = locale.numberNames[number];
}
result += locale.powerNames[1];
if (previousNumber != 0) {
result += " " + locale.numberNames[previousNumber.toString()];
}
}
return result;
}
Finally, locale examples:
var locale = { // English
numberNames: {1: "one", 2: "two", 3: "three", 4: "four", 5: "five", 6: "six", 7: "seven", 8: "eight", 9: "nine" },
powerNames: {0: "", 1: "ty", 2: " hundred", 3: " thousand" },
specialTeenNames: {0: "ten", 1: "eleven", 2: "twelve" },
specialTyNames: {2: "twen", 3: "thir", 5: "fif" },
teenSuffix: "teen"
};
var locale = { // Estonian
numberNames: {1: "üks", 2: "kaks", 3: "kolm", 4: "neli", 5: "viis", 6: "kuus", 7: "seitse", 8: "kaheksa", 9: "üheksa"},
powerNames: {0: "", 1: "kümmend", 2: "sada", 3: " tuhat" },
specialTeenNames: {0: "kümme"},
specialTyNames: {},
teenSuffix: "teist"
};
Here's a JSFiddle with tests: https://jsfiddle.net/rcrxna7v/15/
Function that will work with decimal values also
function amountToWords(amountInDigits){
// American Numbering System
var th = ['','thousand','million', 'billion','trillion'];
var dg = ['zero','one','two','three','four', 'five','six','seven','eight','nine'];
var tn = ['ten','eleven','twelve','thirteen', 'fourteen','fifteen','sixteen', 'seventeen','eighteen','nineteen'];
var tw = ['twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
function toWords(s){
s = s.toString();
s = s.replace(/[\, ]/g,'');
if (s != parseFloat(s))
return 'not a number';
var x = s.indexOf('.');
if (x == -1) x = s.length;
if (x > 15) return 'too big';
var n = s.split('');
var str = '';
var sk = 0;
for (var i=0; i < x; i++){
if ((x-i)%3==2){
if (n[i] == '1') {
str += tn[Number(n[i+1])] + ' ';
i++; sk=1;
} else if (n[i]!=0) {
str += tw[n[i]-2] + ' ';sk=1;
}
} else if (n[i]!=0) {
str += dg[n[i]] +' ';
if ((x-i)%3==0)
str += 'hundred ';
sk=1;
} if ((x-i)%3==1) {
if (sk) str += th[(x-i-1)/3] + ' ';sk=0;
}
}
if (x != s.length) {
var y = s.length;
str += 'point ';
for (var i=x+1; i<y; i++) str += dg[n[i]] +' ';
}
return str.replace(/\s+/g,' ');
}
return toWords(amountInDigits);
}
<input type="text" name="number" placeholder="Number OR Amount" onkeyup="word.innerHTML=amountToWords(this.value)" />
<div id="word"></div>
I modified #McShaman's code, converted it to CoffeeScript, and added docs via JSNice. Here's the result, for those interested (English):
###
Convert an integer to an English string equivalent
#param {Integer} number the integer to be converted
#return {String} the English number equivalent
###
inWords = (number) ->
###
#property {Array}
###
englishIntegers = [
""
"one "
"two "
"three "
"four "
"five "
"six "
"seven "
"eight "
"nine "
"ten "
"eleven "
"twelve "
"thirteen "
"fourteen "
"fifteen "
"sixteen "
"seventeen "
"eighteen "
"nineteen "
]
###
#property {Array}
###
englishIntegerTens = [
""
""
"twenty"
"thirty"
"forty"
"fifty"
"sixty"
"seventy"
"eighty"
"ninety"
]
###
#property {Array}
###
englishIntegerThousands = [
"thousand"
"million"
""
]
number = number.toString()
return "" if number.length > 9
###
#property {string}
###
number = ("000000000" + number).substr(-9)
###
#property {(Array.<string>|null)}
###
number = number.match(/.{3}/g)
###
#property {string}
###
convertedWords = ""
###
#property {number}
###
i = 0
while i < englishIntegerThousands.length
###
#property {string}
###
currentNumber = number[i]
###
#property {string}
###
tempResult = ""
tempResult += (if convertedWords isnt "" then " " + englishIntegerThousands[i] + " " else "")
tempResult += (if currentNumber[0] isnt 0 then englishIntegers[Number(currentNumber[0])] + "hundred " else "")
###
#property {string}
###
currentNumber = currentNumber.substr(1)
tempResult += (if currentNumber isnt 0 then ((if tempResult isnt "" then "and " else "")) + (englishIntegers[Number(currentNumber)] or englishIntegerTens[currentNumber[0]] + " " + englishIntegers[currentNumber[1]]) else "")
convertedWords += tempResult
i++
convertedWords
Though, this question has been answered - still I want to share something I recently developed in java script (based on the logic of an old C#. Net implementation I found in Internet) for converting Indian currency values to Words. It can handle up to 40 digits. You can have a look.
Usage:
InrToWordConverter.Initialize();.
var inWords = InrToWordConverter.ConvertToWord(amount);
Implementation:
htPunctuation = {};
listStaticSuffix = {};
listStaticPrefix = {};
listHelpNotation = {};
var InrToWordConverter = function () {
};
InrToWordConverter.Initialize = function () {
InrToWordConverter.LoadStaticPrefix();
InrToWordConverter.LoadStaticSuffix();
InrToWordConverter.LoadHelpofNotation();
};
InrToWordConverter.ConvertToWord = function (value) {
value = value.toString();
if (value) {
var tokens = value.split(".");
var rsPart = "";
var psPart = "";
if (tokens.length === 2) {
rsPart = String.trim(tokens[0]) || "0";
psPart = String.trim(tokens[1]) || "0";
}
else if (tokens.length === 1) {
rsPart = String.trim(tokens[0]) || "0";
psPart = "0";
}
else {
rsPart = "0";
psPart = "0";
}
htPunctuation = {};
var rsInWords = InrToWordConverter.ConvertToWordInternal(rsPart) || "Zero";
var psInWords = InrToWordConverter.ConvertToWordInternal(psPart) || "Zero";
var result = "Rupees " + rsInWords + "and " + psInWords + " Paise.";
return result;
}
};
InrToWordConverter.ConvertToWordInternal = function (value) {
var convertedString = "";
if (!(value.toString().length > 40))
{
if (InrToWordConverter.IsNumeric(value.toString()))
{
try
{
var strValue = InrToWordConverter.Reverse(value);
switch (strValue.length)
{
case 1:
if (parseInt(strValue.toString()) > 0) {
convertedString = InrToWordConverter.GetWordConversion(value);
}
else {
convertedString = "Zero ";
}
break;
case 2:
convertedString = InrToWordConverter.GetWordConversion(value);
break;
default:
InrToWordConverter.InsertToPunctuationTable(strValue);
InrToWordConverter.ReverseHashTable();
convertedString = InrToWordConverter.ReturnHashtableValue();
break;
}
}
catch (exception) {
convertedString = "Unexpected Error Occured <br/>";
}
}
else {
convertedString = "Please Enter Numbers Only, Decimal Values Are not supported";
}
}
else {
convertedString = "Please Enter Value in Less Then or Equal to 40 Digit";
}
return convertedString;
};
InrToWordConverter.IsNumeric = function (valueInNumeric) {
var isFine = true;
valueInNumeric = valueInNumeric || "";
var len = valueInNumeric.length;
for (var i = 0; i < len; i++) {
var ch = valueInNumeric[i];
if (!(ch >= '0' && ch <= '9')) {
isFine = false;
break;
}
}
return isFine;
};
InrToWordConverter.ReturnHashtableValue = function () {
var strFinalString = "";
var keysArr = [];
for (var key in htPunctuation) {
keysArr.push(key);
}
for (var i = keysArr.length - 1; i >= 0; i--) {
var hKey = keysArr[i];
if (InrToWordConverter.GetWordConversion((htPunctuation[hKey]).toString()) !== "") {
strFinalString = strFinalString + InrToWordConverter.GetWordConversion((htPunctuation[hKey]).toString()) + InrToWordConverter.StaticPrefixFind((hKey).toString());
}
}
return strFinalString;
};
InrToWordConverter.ReverseHashTable = function () {
var htTemp = {};
for (var key in htPunctuation) {
var item = htPunctuation[key];
htTemp[key] = InrToWordConverter.Reverse(item.toString());
}
htPunctuation = {};
htPunctuation = htTemp;
};
InrToWordConverter.InsertToPunctuationTable = function (strValue) {
htPunctuation[1] = strValue.substr(0, 3).toString();
var j = 2;
for (var i = 3; i < strValue.length; i = i + 2) {
if (strValue.substr(i).length > 0) {
if (strValue.substr(i).length >= 2) {
htPunctuation[j] = strValue.substr(i, 2).toString();
}
else {
htPunctuation[j] = strValue.substr(i, 1).toString();
}
}
else {
break;
}
j++;
}
};
InrToWordConverter.Reverse = function (strValue) {
var reversed = "";
for (var i in strValue) {
var ch = strValue[i];
reversed = ch + reversed;
}
return reversed;
};
InrToWordConverter.GetWordConversion = function (inputNumber) {
var toReturnWord = "";
if (inputNumber.length <= 3 && inputNumber.length > 0) {
if (inputNumber.length === 3) {
if (parseInt(inputNumber.substr(0, 1)) > 0) {
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(0, 1)) + "Hundred ";
}
var tempString = InrToWordConverter.StaticSuffixFind(inputNumber.substr(1, 2));
if (tempString === "")
{
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(1, 1) + "0");
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(2, 1));
}
toReturnWord = toReturnWord + tempString;
}
if (inputNumber.length === 2)
{
var tempString = InrToWordConverter.StaticSuffixFind(inputNumber.substr(0, 2));
if (tempString === "")
{
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(0, 1) + "0");
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(1, 1));
}
toReturnWord = toReturnWord + tempString;
}
if (inputNumber.length === 1)
{
toReturnWord = toReturnWord + InrToWordConverter.StaticSuffixFind(inputNumber.substr(0, 1));
}
}
return toReturnWord;
};
InrToWordConverter.StaticSuffixFind = function (numberKey) {
var valueFromNumber = "";
for (var key in listStaticSuffix) {
if (String.trim(key.toString()) === String.trim(numberKey)) {
valueFromNumber = listStaticSuffix[key].toString();
break;
}
}
return valueFromNumber;
};
InrToWordConverter.StaticPrefixFind = function (numberKey) {
var valueFromNumber = "";
for (var key in listStaticPrefix) {
if (String.trim(key) === String.trim(numberKey)) {
valueFromNumber = listStaticPrefix[key].toString();
break;
}
}
return valueFromNumber;
};
InrToWordConverter.StaticHelpNotationFind = function (numberKey) {
var helpText = "";
for (var key in listHelpNotation) {
if (String.trim(key.toString()) === String.trim(numberKey)) {
helpText = listHelpNotation[key].toString();
break;
}
}
return helpText;
};
InrToWordConverter.LoadStaticPrefix = function () {
listStaticPrefix[2] = "Thousand ";
listStaticPrefix[3] = "Lac ";
listStaticPrefix[4] = "Crore ";
listStaticPrefix[5] = "Arab ";
listStaticPrefix[6] = "Kharab ";
listStaticPrefix[7] = "Neel ";
listStaticPrefix[8] = "Padma ";
listStaticPrefix[9] = "Shankh ";
listStaticPrefix[10] = "Maha-shankh ";
listStaticPrefix[11] = "Ank ";
listStaticPrefix[12] = "Jald ";
listStaticPrefix[13] = "Madh ";
listStaticPrefix[14] = "Paraardha ";
listStaticPrefix[15] = "Ant ";
listStaticPrefix[16] = "Maha-ant ";
listStaticPrefix[17] = "Shisht ";
listStaticPrefix[18] = "Singhar ";
listStaticPrefix[19] = "Maha-singhar ";
listStaticPrefix[20] = "Adant-singhar ";
};
InrToWordConverter.LoadStaticSuffix = function () {
listStaticSuffix[1] = "One ";
listStaticSuffix[2] = "Two ";
listStaticSuffix[3] = "Three ";
listStaticSuffix[4] = "Four ";
listStaticSuffix[5] = "Five ";
listStaticSuffix[6] = "Six ";
listStaticSuffix[7] = "Seven ";
listStaticSuffix[8] = "Eight ";
listStaticSuffix[9] = "Nine ";
listStaticSuffix[10] = "Ten ";
listStaticSuffix[11] = "Eleven ";
listStaticSuffix[12] = "Twelve ";
listStaticSuffix[13] = "Thirteen ";
listStaticSuffix[14] = "Fourteen ";
listStaticSuffix[15] = "Fifteen ";
listStaticSuffix[16] = "Sixteen ";
listStaticSuffix[17] = "Seventeen ";
listStaticSuffix[18] = "Eighteen ";
listStaticSuffix[19] = "Nineteen ";
listStaticSuffix[20] = "Twenty ";
listStaticSuffix[30] = "Thirty ";
listStaticSuffix[40] = "Fourty ";
listStaticSuffix[50] = "Fifty ";
listStaticSuffix[60] = "Sixty ";
listStaticSuffix[70] = "Seventy ";
listStaticSuffix[80] = "Eighty ";
listStaticSuffix[90] = "Ninty ";
};
InrToWordConverter.LoadHelpofNotation = function () {
listHelpNotation[2] = "=1,000 (3 Trailing Zeros)";
listHelpNotation[3] = "=1,00,000 (5 Trailing Zeros)";
listHelpNotation[4] = "=1,00,00,000 (7 Trailing Zeros)";
listHelpNotation[5] = "=1,00,00,00,000 (9 Trailing Zeros)";
listHelpNotation[6] = "=1,00,00,00,00,000 (11 Trailing Zeros)";
listHelpNotation[7] = "=1,00,00,00,00,00,000 (13 Trailing Zeros)";
listHelpNotation[8] = "=1,00,00,00,00,00,00,000 (15 Trailing Zeros)";
listHelpNotation[9] = "=1,00,00,00,00,00,00,00,000 (17 Trailing Zeros)";
listHelpNotation[10] = "=1,00,00,00,00,00,00,00,00,000 (19 Trailing Zeros)";
listHelpNotation[11] = "=1,00,00,00,00,00,00,00,00,00,000 (21 Trailing Zeros)";
listHelpNotation[12] = "=1,00,00,00,00,00,00,00,00,00,00,000 (23 Trailing Zeros)";
listHelpNotation[13] = "=1,00,00,00,00,00,00,00,00,00,00,00,000 (25 Trailing Zeros)";
listHelpNotation[14] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,000 (27 Trailing Zeros)";
listHelpNotation[15] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (29 Trailing Zeros)";
listHelpNotation[16] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (31 Trailing Zeros)";
listHelpNotation[17] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (33 Trailing Zeros)";
listHelpNotation[18] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (35 Trailing Zeros)";
listHelpNotation[19] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (37 Trailing Zeros)";
listHelpNotation[20] = "=1,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,000 (39 Trailing Zeros)";
};
if (!String.trim) {
String.trim = function (str) {
var result = "";
var firstNonWhiteSpaceFound = false;
var startIndex = -1;
var endIndex = -1;
if (str) {
for (var i = 0; i < str.length; i++) {
if (firstNonWhiteSpaceFound === false) {
if (str[i] === ' ' || str[i] === '\t') {
continue;
}
else {
firstNonWhiteSpaceFound = true;
startIndex = i;
endIndex = i;
}
}
else {
if (str[i] === ' ' || str[i] === '\t') {
continue;
}
else {
endIndex = i;
}
}
}
if (startIndex !== -1 && endIndex !== -1) {
result = str.slice(startIndex, endIndex + 1);
}
}
return result;
};
}
Try this code with a Turkish currency compliant JavaScript
function dene() {
var inpt = document.getElementById("tar1").value;
var spt = inpt.split('');
spt.reverse();
var tek = ["", "Bir", "İki", "Üç", "Dört", "Beş", "Altı", "Yedi", "Sekiz", "Dokuz"];
var onlu = ["", "On", "Yirmi", "Otuz", "Kırk", "Elli", "Atmış", "Yetmiş", "Seksen", "Doksan"];
var Yuz = ["", "Yüz", "İkiYüz", "Üçyüz", "DörtYüz", "BeşYüz", "AltıYüz", "YediYüz", "SekizYüz", "DokuzYüz"];
var ska = ["", "", "", "", "Bin", "Milyon", "Milyar", "Trilyon", "Katrilyon", "Kentilyon"];
var i, j;
var bas3 = "";
var bas6 = "";
var bas9 = "";
var bas12 = "";
var total;
for(i = 0; i < 1; i++) {
bas3 += Yuz[spt[i+2]] + onlu[spt[i+1]] + tek[spt[i]];
bas6 += Yuz[spt[i+5]] + onlu[spt[i+4]] + tek[spt[i+3]] + ska[4];
bas9 += Yuz[spt[i+8]] + onlu[spt[i+7]] + tek[spt[i+6]] + ska[5];
bas12 += Yuz[spt[i+11]] + onlu[spt[i+10]] + tek[spt[i+9]] + ska[6];
if(inpt.length < 4) {
bas6 = '';
bas9 = '';
}
if(inpt.length > 6 && inpt.slice(5, 6) == 0) {
bas6 = bas6.replace(/Bin/g, '');
}
if(inpt.length < 7) {
bas9 = '';
}
if(inpt.length > 9 && inpt.slice(1,3) == 000){
bas9 = bas9.replace(/Milyon/g, '');
}
if(inpt.length < 10) {
bas12 = '';
}
}
total = bas12 + bas9 + bas6 + bas3;
total = total.replace(NaN, '');
total = total.replace(undefined, '');
document.getElementById('demo').innerHTML =
total;
}
Lot of good answers. I needed mine for Indian (South Asian) numbering system. I modified one of the codes above - attaching it here, in case, someone else needs this. In the Indian numbering system, groups after thousands are in in 2 digits, not 3 as in the western system.
var IS_SOUTH_ASIAN = true;
function int_to_words(int) {
if (int === 0) return 'zero';
var ONES_WORD = ['','one','two','three','four','five','six','seven','eight','nine','ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen'];
var TENS_WORD = ['','','twenty','thirty','fourty','fifty','sixty','seventy','eighty','ninety'];
var SCALE_WORD_WESTERN = ['','thousand','million','billion','trillion','quadrillion','quintillion','sextillion','septillion','octillion','nonillion'];
var SCALE_WORD_SOUTH_ASIAN = ['','thousand','lakh','crore','arab','kharab','neel','padma','shankh','***','***'];
var GROUP_SIZE = (typeof IS_SOUTH_ASIAN != "undefined" && IS_SOUTH_ASIAN) ? 2 : 3;
var SCALE_WORD = (typeof IS_SOUTH_ASIAN != "undefined" && IS_SOUTH_ASIAN) ? SCALE_WORD_SOUTH_ASIAN : SCALE_WORD_WESTERN;
// Return string of first three digits, padded with zeros if needed
function get_first_3(str) {
return ('000' + str).substr(-(3));
}
function get_first(str) { //-- Return string of first GROUP_SIZE digits, padded with zeros if needed, if group size is 2, make it size 3 by prefixing with a '0'
return (GROUP_SIZE == 2 ? '0' : '') + ('000' + str).substr(-(GROUP_SIZE));
}
// Return string of digits with first three digits chopped off
function get_rest_3(str) {
return str.substr(0, str.length - 3);
}
function get_rest(str) { // Return string of digits with first GROUP_SIZE digits chopped off
return str.substr(0, str.length - GROUP_SIZE);
}
// Return string of triplet convereted to words
function triplet_to_words(_3rd, _2nd, _1st) {
return (_3rd == '0' ? '' : ONES_WORD[_3rd] + ' hundred ') +
(_1st == '0' ? TENS_WORD[_2nd] : TENS_WORD[_2nd] && TENS_WORD[_2nd] + '-' || '') +
(ONES_WORD[_2nd + _1st] || ONES_WORD[_1st]); //-- 1st one returns one-nineteen - second one returns one-nine
}
// Add to result, triplet words with scale word
function add_to_result(result, triplet_words, scale_word) {
return triplet_words ? triplet_words + (scale_word && ' ' + scale_word || '') + ' ' + result : result;
}
function recurse (result, scaleIdx, first, rest) {
if (first == '000' && rest.length === 0) return result;
var newResult = add_to_result (result, triplet_to_words (first[0], first[1], first[2]), SCALE_WORD[scaleIdx]);
return recurse (newResult, ++scaleIdx, get_first(rest), get_rest(rest));
}
return recurse ('', 0, get_first_3(String(int)), get_rest_3(String(int)));
}
while this system does use a for loop, It uses US english and is fast, accurate, and expandable(you can add infinite values to the "th" var and they will be included).
This function grabs the 3 groups of numbers backwards so it can get the number groups where a , would normally separate them in the numeric form. Then each group of three numbers is added to an array with the word form of just the 3 numbers(ex: one hundred twenty three). It then takes that new array list, and reverses it again, while adding the th var of the same index to the end of the string.
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 ', 'hundred '];
var th = ['', 'thousand ','million ','billion ', 'trillion '];
function numberToWord(number){
var text = "";
var size = number.length;
var textList = [];
var textListCount = 0;
//get each 3 digit numbers
for(var i = number.length-1; i >= 0; i -= 3){
//get 3 digit group
var num = 0;
if(number[(i-2)]){num += number[(i-2)];}
if(number[(i-1)]){num += number[(i-1)];}
if(number[i]){num += number[i];}
//remove any extra 0's from begining of number
num = Math.floor(num).toString();
if(num.length == 1 || num < 20){
//if one digit or less than 20
textList[textListCount] = ones[num];
}else if(num.length == 2){
//if 2 digits and greater than 20
textList[textListCount] = tens[num[0]]+ones[num[1]];
}else if(num.length == 3){
//if 3 digits
textList[textListCount] = ones[num[0]]+tens[10]+tens[num[1]]+ones[num[2]];
}
textListCount++;
}
//add the list of 3 digit groups to the string
for(var i = textList.length-1; i >= 0; i--){
if(textList[i] !== ''){text += textList[i]+th[i];} //skip if the number was 0
}
return text;
}
This is also in response to naomik's excellent post! Unfortunately I don't have the rep to post in the correct place but I leave this here in case it can help anyone.
If you need British English written form you need to make some adaptions to the code. British English differs from the American in a couple of ways. Basically you need to insert the word 'and' in two specific places.
After a hundred assuming there are tens and ones. E.g One hundred and ten. One thousand and seventeen. NOT One thousand one hundred and.
In certain edges, after a thousand, a million, a billion etc. when there are no smaller units. E.g. One thousand and ten. One million and forty four. NOT One million and one thousand.
The first situation can be addressed by checking for 10s and 1s in the makeGroup method and appending 'and' when they exist.
makeGroup = ([ones,tens,huns]) => {
var adjective = this.num(ones) ? ' hundred and ' : this.num(tens) ? ' hundred and ' : ' hundred';
return [
this.num(huns) === 0 ? '' : this.a[huns] + adjective,
this.num(ones) === 0 ? this.b[tens] : this.b[tens] && this.b[tens] + '-' || '',
this.a[tens+ones] || this.a[ones]
].join('');
};
The second case is more complicated. It is equivalent to
add 'and' to 'a million, a thousand', or 'a billion' if the antepenultimate number is zero. e.g.
1,100,057 one million one hundred thousand and fifty seven.
5,000,006 five million and six
I think this could be implemented in #naomik's code through the use of a filter function but I wasn't able to work out how. In the end I settled on hackily looping through the returned array of words and using indexOf to look for instances where the word 'hundred' was missing from the final element.
I've just written paisa.js to do this, and it handles lakhs and crores correctly as well, can check it out. The core looks a bit like this:
const regulars = [
{
1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine'
},
{
2: 'twenty', 3: 'thirty', 4: 'forty', 5: 'fifty', 6: 'sixty', 7: 'seventy', 8: 'eighty', 9: 'ninety'
}
]
const exceptions = {
10: 'ten',
11: 'eleven',
12: 'twelve',
13: 'thirteen',
14: 'fourteen',
15: 'fifteen',
16: 'sixteen',
17: 'seventeen',
18: 'eighteen',
19: 'nineteen'
}
const partInWords = (part) => {
if (parseInt(part) === 0) return
const digits = part.split('')
const words = []
if (digits.length === 3) {
words.push([regulars[0][digits.shift()], 'hundred'].join(' '))
}
if (exceptions[digits.join('')]) {
words.push(exceptions[digits.join('')])
} else {
words.push(digits.reverse().reduce((memo, el, i) => {
memo.unshift(regulars[i][el])
return memo
}, []).filter(w => w).join(' '))
}
return words.filter(w => w.trim().length).join(' and ')
}
My solution is based on Juan Gaitán's solution for Indian currency, works up to crores.
function valueInWords(value) {
let ones = ['', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'];
let tens = ['twenty','thirty', 'forty','fifty', 'sixty', 'seventy', 'eighty', 'ninety'];
let digit = 0;
if (value < 20) return ones[value];
if (value < 100) {
digit = value % 10; //remainder
return tens[Math.floor(value/10)-2] + " " + (digit > 0 ? ones[digit] : "");
}
if (value < 1000) {
return ones[Math.floor(value/100)] + " hundred " + (value % 100 > 0 ? valueInWords(value % 100) : "");
}
if (value < 100000) {
return valueInWords(Math.floor(value/1000)) + " thousand " + (value % 1000 > 0 ? valueInWords(value % 1000) : "");
}
if (value < 10000000) {
return valueInWords(Math.floor(value/100000)) + " lakh " + (value % 100000 > 0 ? valueInWords(value % 100000) : "");
}
return valueInWords(Math.floor(value/10000000)) + " crore " + (value % 10000000 > 0 ? valueInWords(value % 10000000) : "");
}
function numberToEnglish( n ) {
var string = n.toString(), units, tens, scales, start, end, chunks, chunksLen, chunk, ints, i, word, words, and = 'and';
/* Remove spaces and commas */
string = string.replace(/[, ]/g,"");
/* Is number zero? */
if( parseInt( string ) === 0 ) {
return 'zero';
}
/* Array of units as words */
units = [ '', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' ];
/* Array of tens as words */
tens = [ '', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety' ];
/* Array of scales as words */
scales = [ '', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion', 'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quatttuor-decillion', 'quindecillion', 'sexdecillion', 'septen-decillion', 'octodecillion', 'novemdecillion', 'vigintillion', 'centillion' ];
/* Split user argument into 3 digit chunks from right to left */
start = string.length;
chunks = [];
while( start > 0 ) {
end = start;
chunks.push( string.slice( ( start = Math.max( 0, start - 3 ) ), end ) );
}
/* Check if function has enough scale words to be able to stringify the user argument */
chunksLen = chunks.length;
if( chunksLen > scales.length ) {
return '';
}
/* Stringify each integer in each chunk */
words = [];
for( i = 0; i < chunksLen; i++ ) {
chunk = parseInt( chunks[i] );
if( chunk ) {
/* Split chunk into array of individual integers */
ints = chunks[i].split( '' ).reverse().map( parseFloat );
/* If tens integer is 1, i.e. 10, then add 10 to units integer */
if( ints[1] === 1 ) {
ints[0] += 10;
}
/* Add scale word if chunk is not zero and array item exists */
if( ( word = scales[i] ) ) {
words.push( word );
}
/* Add unit word if array item exists */
if( ( word = units[ ints[0] ] ) ) {
words.push( word );
}
/* Add tens word if array item exists */
if( ( word = tens[ ints[1] ] ) ) {
words.push( word );
}
/* Add 'and' string after units or tens integer if: */
if( ints[0] || ints[1] ) {
/* Chunk has a hundreds integer or chunk is the first of multiple chunks */
if( ints[2] || ! i && chunksLen ) {
words.push( and );
}
}
/* Add hundreds word if array item exists */
if( ( word = units[ ints[2] ] ) ) {
words.push( word + ' hundred' );
}
}
}
return words.reverse().join( ' ' );
}
// - - - - - Tests - - - - - -
function test(v) {
var sep = ('string'==typeof v)?'"':'';
console.log("numberToEnglish("+sep + v.toString() + sep+") = "+numberToEnglish(v));
}
test(2);
test(721);
test(13463);
test(1000001);
test("21,683,200,000,621,384");
For those who are looking for imperial/english naming conventions.
Based on #Salman's answer
var a = ['','one ','two ','three ','four ', 'five ','six ','seven ','eight ','nine ','ten ','eleven ','twelve ','thirteen ','fourteen ','fifteen ','sixteen ','seventeen ','eighteen ','nineteen '];
var b = ['', '', 'twenty','thirty','forty','fifty', 'sixty','seventy','eighty','ninety'];
function inWords (num) {
if ((num = num.toString()).length > 12) return 'overflow';
n = ('00000000000' + num).substr(-12).match(/^(\d{3})(\d{3})(\d{3})(\d{1})(\d{2})$/);
if (!n) return; var str = '';
str += (n[1] != 0) ? (Number(n[1]) > 99 ? this.a[Number(n[1][0])] + 'hundred ' : '') + (a[Number(n[1])] || b[n[1][1]] + ' ' + a[n[1][2]]) + 'billion ' : '';
str += (n[2] != 0) ? (Number(n[2]) > 99 ? this.a[Number(n[2][0])] + 'hundred ' : '') + (a[Number(n[2])] || b[n[2][1]] + ' ' + a[n[2][2]]) + 'million ' : '';
str += (n[3] != 0) ? (Number(n[3]) > 99 ? this.a[Number(n[3][0])] + 'hundred ' : '') + (a[Number(n[3])] || b[n[3][1]] + ' ' + a[n[3][2]]) + 'thousand ' : '';
str += (n[4] != 0) ? (a[Number(n[4])] || b[n[4][0]] + ' ' + a[n[4][1]]) + 'hundred ' : '';
str += (Number(n[5]) !== 0) ? ((str !== '') ? 'and ' : '') +
(this.a[Number(n[5])] || this.b[n[5][0]] + ' ' +
this.a[n[5][1]]) + '' : '';
return str;
}
document.getElementById('number').onkeyup = function () {
document.getElementById('words').innerHTML = inWords(document.getElementById('number').value);
};
<span id="words"></span>
<input id="number" type="text" />
Cleanest and easiest approach that came to mind:
const numberText = {
1: 'one',
2: 'two',
3: 'three',
4: 'four',
5: 'five',
6: 'six',
7: 'seven',
8: 'eight',
9: 'nine',
10: 'ten',
11: 'eleven',
12: 'twelve',
13: 'thirteen',
14: 'fourteen',
15: 'fifteen',
16: 'sixteen',
17: 'seventeen',
18: 'eighteen',
19: 'nineteen',
20: 'twenty',
30: 'thirty',
40: 'forty',
50: 'fifty',
60: 'sixty',
70: 'seventy',
80: 'eighty',
90: 'ninety',
100: 'hundred',
1000: 'thousand',
}
const numberValues = Object.keys(numberText)
.map((val) => Number(val))
.sort((a, b) => b - a)
const convertNumberToEnglishText = (n) => {
if (n === 0) return 'zero'
if (n < 0) return 'negative ' + convertNumberToEnglishText(-n)
let num = n
let text = ''
for (const numberValue of numberValues) {
const count = Math.trunc(num / numberValue)
if (count < 1) continue
if (numberValue >= 100) text += convertNumberToEnglishText(count) + ' '
text += numberText[numberValue] + ' '
num -= count * numberValue
}
if (num !== 0) throw Error('Something went wrong!')
return text.trim()
}
Probably the simplest one I got and used was from Ben E. I made modifications to his code since it would only return for example 'Five Hundred' when you try to convert 500,000.00. I just added a line of conditional code to fix it. Also added the provision for giving out the last two decimal places. I'm now using it to convert the amount to words when printing checks. Here was my revision added to it:
if (Math.floor((number%(100*Math.pow(1000,i))/Math.pow(1000,i))) == 0) {
word = first[Math.floor(tempNumber/(100*Math.pow(1000,i)))] + 'Hundred ' + mad[i]
+ ' ' + word;
} else {
I'm having a hard time pasting the code here but let me know if you need any clarifications
answared by #pramod kharade
simplified
function NumToWord(inputNumber) {
var str = new String(inputNumber)
var splt = str.split("");
var rev = splt.reverse();
var once = ['Zero', ' One', ' Two', ' Three', ' Four', ' Five', ' Six', ' Seven', ' Eight', ' Nine'];
var twos = ['Ten', ' Eleven', ' Twelve', ' Thirteen', ' Fourteen', ' Fifteen', ' Sixteen', ' Seventeen', ' Eighteen', ' Nineteen'];
var tens = ['', 'Ten', ' Twenty', ' Thirty', ' Forty', ' Fifty', ' Sixty', ' Seventy', ' Eighty', ' Ninety'];
numLength = rev.length;
var word = new Array();
var j = 0;
for (i = 0; i < numLength; i++) {
switch (i) {
case 0:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = '' + once[rev[i]];
}
word[j] = word[j];
break;
case 1:
aboveTens();
break;
case 2:
if (rev[i] == 0) {
word[j] = '';
}
else if ((rev[i - 1] == 0) || (rev[i - 2] == 0)) {
word[j] = once[rev[i]] + " Hundred ";
}
else {
word[j] = once[rev[i]] + " Hundred and";
}
break;
case 3:
if (rev[i] == 0 || rev[i + 1] == 1) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if ((rev[i + 1] != 0) || (rev[i] > 0)) {
word[j] = word[j] + " Thousand";
}
break;
case 4:
aboveTens();
break;
case 5:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if (rev[i + 1] !== '0' || rev[i] > '0') {
word[j] = word[j] + " Lakh";
}
break;
case 6:
aboveTens();
break;
case 7:
if ((rev[i] == 0) || (rev[i + 1] == 1)) {
word[j] = '';
}
else {
word[j] = once[rev[i]];
}
if (rev[i + 1] !== '0' || rev[i] > '0') {
word[j] = word[j] + " Crore";
}
break;
case 8:
aboveTens();
break;
default: break;
}
j++;
}
function aboveTens() {
if (rev[i] == 0) { word[j] = ''; }
else if (rev[i] == 1) { word[j] = twos[rev[i - 1]]; }
else { word[j] = tens[rev[i]]; }
}
word.reverse();
var finalOutput = '';
for (i = 0; i < numLength; i++) {
finalOutput = finalOutput + word[i];
}
return finalOutput;
}
console.log(NumToWord(123))
console.log(NumToWord(12345678))
console.log(NumToWord(12334543))
console.log(NumToWord(6789876123))
Convertirlos en Español
class Converter {
constructor() {
this.unit = ['CERO', 'UN', 'DOS', 'TRES', 'CUATRO', 'CINCO', 'SEIS', 'SIETE', 'OCHO', 'NUEVE'];
this.units = ['CERO', 'UNO', 'DOS', 'TRES', 'CUATRO', 'CINCO', 'SEIS', 'SIETE', 'OCHO', 'NUEVE'];
this.tenToSixteen = ['DIEZ', 'ONCE', 'DOCE', 'TRECE', 'CATORCE', 'QUINCE', 'DIECISEIS'];
this.tens = ['TREINTA', 'CUARENTA', 'CINCUENTA', 'SESENTA', 'SETENTA', 'OCHENTA', 'NOVENTA'];
this.monedaSingular = " PESO";
this.monedaPlural = " PESOS";
this.monedaMillon = " DE PESOS";
this.centavoSingular = " CENTAVO"
this.centavoPlural = " CENTAVOS"
this.elMessage = document.getElementById('message');
this.addListener();
}
addListener() {
let elInput = document.getElementById('field-number');
elInput.addEventListener('keyup', () => {
if (elInput.value !== '') {
this.convertToText(elInput.value);
} else {
this.elMessage.innerText = '';
}
});
}
convertToText(number) {
number = this.deleteZerosLeft(number);
if (!this.validateNumber(number)) {
this.elMessage.innerText = 'Sólo se aceptan números enteros positivos.';
return;
}
let num = number;
number = number.split(".")[0];
let entero = this.getName(number);
let moneda;
if (parseInt(number) == 1) {
//this.elMessage.innerText =
moneda = entero + this.monedaSingular;
} else {
moneda = entero + this.monedaPlural;
}
if (num.indexOf('.') >= 0) {
let d = num.split(".")[1];
d = this.getName(d);
if (parseInt(d) == 0) {
moneda = moneda;
} else if (parseInt(d) == 1) {
moneda = moneda + " CON " + d + " " + this.centavoSingular;
} else {
moneda = moneda + " CON " + d + " " + this.centavoPlural;
}
}
this.elMessage.innerText = moneda;
}
// Elimina los ceros a la izquierda
deleteZerosLeft(number) {
let i = 0;
let isZero = true;
for (i = 0; i < number.length; i++) {
if (number.charAt(i) != 0) {
isZero = false;
break;
}
}
return isZero ? '0' : number.substr(i);
}
validateNumber(number) {
// Validar que la cadena sea un número y que no esté vacía
if (isNaN(number) || number === '') {
return false;
}
// Validar que el número no sea negativo
if (number.indexOf('-') >= 0) {
return false;
}
return true;
}
getName(number) {
number = this.deleteZerosLeft(number);
if (number.length === 1) {
return this.getUnits(number);
}
if (number.length === 2) {
return this.getTens(number);
}
if (number.length === 3) {
return this.getHundreds(number);
}
if (number.length < 7) {
return this.getThousands(number);
}
if (number.length < 13) {
return this.getPeriod(number, 6, 'MILLON');
}
if (number.length < 19) {
return this.getPeriod(number, 12, 'BILLON');
}
return 'Número demasiado grande.';
}
getUnits(number) {
let numberInt = parseInt(number);
return this.unit[numberInt];
}
getTens(number) {
// Obtener las unidades
let units = number.charAt(1);
if (number < 17) {
return this.tenToSixteen[number - 10];
}
if (number < 20) {
return 'DIECI' + this.getUnits(units);
}
// Nombres especiales
switch (number) {
case '20':
return 'VEINTE';
case '22':
return 'VEINTIDOS';
case '23':
return 'VEINTITRES';
case '26':
return 'VEINTISEIS';
}
if (number < 30) {
return 'VEINTI' + this.getUnits(units);
}
let name = this.tens[number.charAt(0) - 3];
if (units > 0) {
name += ' Y ' + this.getUnits(units);
}
return name;
}
getHundreds(number) {
let name = '';
// Obtener las centenas
let hundreds = number.charAt(0);
// Obtener las decenas y unidades
let tens = number.substr(1);
if (number == 100) {
return 'CIEN';
}
// Nombres especiales
switch(hundreds) {
case '1':
name = 'CIENTO';
break;
case '5':
name = 'QUINIENTOS';
break;
case '7':
name = 'SETECIENTOS';
break;
case '9':
name = 'NOVECIENTOS';
}
if (name === '') {
name = this.getUnits(hundreds) + 'CIENTOS';
}
if (tens > 0) {
name += ' ' + this.getName(tens);
}
return name;
}
getThousands(number) {
let name = 'MIL';
// Obtener cuantos dígitos están en los miles
let thousandsLength = number.length - 3;
// Obtener los miles
let thousands = number.substr(0, thousandsLength);
// Obtener las centenas, decenas y unidades
let hundreds = number.substr(thousandsLength);
if (thousands > 1) {
// Se reemplaza la palabra uno por un en numeros como 21000, 31000, 41000, etc.
name = this.getName(thousands).replace('UNO', 'UN') + ' MIL';
}
if (hundreds > 0) {
name += ' ' + this.getName(hundreds);
}
return name;
}
// Obtiene periodos, por ejemplo: millones, billones, etc.
getPeriod(number, digitsToTheRight, periodName) {
let name = 'UN ' + periodName;
// Obtener cuantos dígitos están dentro del periodo
let periodLength = number.length - digitsToTheRight;
// Obtener los dítos del periodo
let periodDigits = number.substr(0, periodLength);
// Obtener los digitos previos al periodo
let previousDigits = number.substr(periodLength);
if (periodDigits > 1) {
name = this.getName(periodDigits).replace('UNO', 'UN') + ' ' + periodName.replace('Ó', 'O') + 'ES';
}
if (previousDigits > 0) {
name += ' ' + this.getName(previousDigits);
}
return name;
}
}
new Converter();