<!doctype html>
<html lang= "en">
<head>
<meta charset= "utf-8">
<title> Number Strings</title>
<style>
body{
font-size:120%;
margin:0 1em;
}
h1 span{
font-weight: bold;
color: navy;
font-size:smaller;
}
h2{
border-top:5px navy ridge;
margin:1em 0;
}
div{
margin:1ex;
position:relative;
}
label, input, button, textarea, select{
font-size:1em;
color:black;
font-weight:600;
}
label, button{
cursor:pointer;
text-decoration:none;
color:black;
font-size:1em;
font-weight:bold;
}
p{margin:1em 0}
button:hover, button:focus{
color:red
}
button:disabled, button:hover:disabled, button:focus:disabled{
cursor:default;
color:gray;
}
textarea, textarea[readonly]{
min-width:500px;
width:90%;
overflow-y:scroll;
margin:1ex auto;
font-weight:600;
background-color:white;
color:black;
font-family:Arial, sans-serif;
}
#numstringDiv{
background-color:white;
color:black;
position:relative;
padding:1em;
max-width:1200px;
}
@media all and(max-width:1000px){
body{
font-size:100%;
}
}
</style>
<script>
/* US English words from numbers*/
Numword={
cashwords: function(n){
n= Number(n);
if(!n) return NaN;
var I= Math.floor(n),
dec= n%1, str= '', r= '';
str= I.toWords() || '';
if(dec){
dec= dec.toFixed(2)*100;
r= dec.toWords();
}
if(I> 0){
str+= ' dollar';
if(I> 1) str+= 's';
if(r) str+= ' and ';
}
if(r){
str+= r+' cent';
if(dec> 1) str += 's';
}
return str;
},
forget: function(){
delete Numword.vocab;
return true;
},
fracValue: function(s, prec){
var I= 0, dec= 0, M=/(\d+ +)?(\d+)\/(\d+)$/.exec(s);
if(M){
if(M[1]) I= +(M[1].trim());
dec= M[2]/M[3];
if(typeof prec== 'number') dec= +(dec.toFixed(prec));
}
return I+dec;
},
getExponent: function(s, sign){
var rx= /(\d+(\.\d+)?|\.\d+)[eE]([+-]?\d+)/, num, pow,
M= rx.exec(s);
if(M){
num= (+M[1]).toWords();
pow= (+M[3]).toWords().ordinal();
return sign+ num+ ' times ten to the '+ pow;
}
return NaN;
},
getWords: function(input, ord){
s= String(input).trim();
var d= s.replace(/(,| and)/g, ''),
Num, I, dec, str= '', r= '',
M, d2, d3, da,
sign= /^-.+/.test(d)? 'minus ':'';
if(sign) d= d.substring(1);
if(/infinity/i.test(s)) return sign? 'Negative Infinity':'Infinity';
if(!s || !/\d/.test(s)) return '';
if(d.charAt(0)=== '$'){
d= Number(d.substring(1));
return d? Numword.cashwords(d):'';
}
else if(d.indexOf('/')!= -1){
return Numword.printFraction(d, sign) || '';
}
if(/^\d+\: *\d+/.test(d)){
return d.match(/\d+/g).map(function(itm){
return (+itm).toWords();
}).join(' ');
}
d= d.replace(/[^\d\.eE+-]/g, '');
da= Number(d);
if(da> Math.pow(10, 17) || da< Math.pow(10, -6)) d= da.toExponential();
else d= String(da);
if(/\d[eE][+-]?\d/.test(d)) return Numword.getExponent(d, sign);
str= da.toWords().trim();
if(da=== Math.round(da) && ord) str= str.ordinal();
return sign+str;
},
ordinal: function(){
var ax, suffix, str= ' '+this.trim();
if(str.charAt(str.length-1)== 'y') return str.slice(0, -2)+'tieth';
var ax= str.lastIndexOf(' ');
suffx= str.substring(ax);
if(ax> 1) str= str.substring(0, ax);
else str= ' ';
switch(suffx.trim()){
case 'one': return str+' first';
case 'two': return str+' second';
case 'three': return str+' third';
case 'five': return str+' fifth';
case 'eight': return str+' eighth';
case 'nine': return str+' ninth';
case 'twelve': return str+' twelfth';
default: return str+suffx+'th';
}
},
printFraction: function(d, sign, ret){
var num, M=/(\d+\s+)?(\d+)\s*\/\s*(\d+)/.exec(d);
if(!M) return NaN;
num= M[1]? (+M[1]).toWords().replace(/ and /g, ' ')+' and ':'';
num+= (+M[2]).toWords()+'-';
if(M[3]=== '2') num+= 'half';
else if(M[3]=== '4') num+= 'quarter';
else num+= (+M[3]).toWords().ordinal();
if(M[2]!== '1') num= num.replace(/([^s])$/, '$1s');
return sign+num.replace(/ *\- */, '-');
},
strums:[
'US-English',
['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'],
['naught', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'],
['hundred', 'thousand', 'million', 'billion', 'trillion', 'quadrillion']
],
toWords: function(ord){
var W= Numword.strums, dec= '', N= '', I,
A= [], L, tem, h, t, t2, o, str,
sign= this<0? 'minus ':'',
n= Math.abs(this);
if(n && !isFinite(n)) return sign+' Infinity';
I= Math.floor(n);
if(n!== I) dec= String(n).split('.')
if(dec[1]){
dec= ' point '+ dec[1].split('').map(function(itm){
return W[1][+itm];
}).join(' ');
if(I=== 0) return sign+'zero'+dec;
else ord= false;
}
while(I> 0){
tem= I%1000;
I= (I-tem)/1000;
if(tem=== 0) A.push('');
else{
str= '';
t= tem%100;
if(tem>= 100){
h= Math.floor(tem/100);
str= W[1][h]+' hundred ';
}
if(t> 0){
if(A.length== 0 && (h> 0 || I> 0)) str+= ' and ';
if(t<20){
if(W[1][t]) str+= W[1][t]+' ';
}
else{
t2= Math.floor(t/10);
o= t%10;
if(W[2][t2]) str+= W[2][t2];
if(o> 0 && W[1][o]) str+= ' '+W[1][o];
}
}
A.push(str);
}
}
N= A.map(function(itm, i){
if(!itm) return '';
var tem= '';
if(i> 0) tem= ' '+W[3][i];
return itm+tem;
}).reverse().join(' ');
if(ord) N= N.ordinal();
N= sign+ N.replace(/ion (?=\S+)/g, 'ion, ')+ dec;
return N.replace(/ {2,}/g, ' ');
}
}
Number.prototype.toWords= function(mod){
return Numword.toWords.call(this, mod);
}
String.prototype.ordinal= function(){
return Numword.ordinal.call(this);
}
/* equalizer for cross-browser support*/
String.prototype.trim= ''.trim || function(){
return this.replace(/^\s+/g, '').replace(/\s+$/g, '');
}
Array.prototype.forEach= [].forEach || function(fun, scope){
var T= this, L= T.length, i= 0;
if(typeof fun== 'function'){
while(i< L){
if(i in T){
fun.call(scope, T[i], i, T);
}
++i;
}
}
return T;
}
Array.prototype.map= [].map || function(fun, scope){
var T= this, L= T.length, A= Array(L), i= 0;
if(typeof fun== 'function'){
while(i< L){
if(i in T){
A[i]= fun.call(scope, T[i], i, T);
}
++i;
}
return A;
}
}
/*end equalizer */
/*demo program */
window.Run={
doc: function(what, pa, hoo, txt, sty){
var tag, el, mod, ref;
what= what.toLowerCase().split('_');
tag= what[0], mod= what[1], ref= mr(pa);
el= document.createElement(tag);
if(hoo) el.id= hoo;
if(sty) el.style.cssText= sty;
if(ref){
if(mod== 'b4') ref.parentNode.insertBefore(el, ref);
else if(mod== 'bf' && ref.firstChild){
ref.insertBefore(el, ref.firstChild);
}
else ref.appendChild(el);
}
if(txt) el.appendChild(document.createTextNode(txt));
return el;
},
sayNext: function(hoo, text, css){
Run.doc('br', hoo);
return Run.doc('span', hoo, '', text, css);
},
zap: function(who){
who= mr(who);
while(who.lastChild) who.removeChild(who.lastChild);
}
}
window.mr= function(hoo){
if(typeof hoo== 'string') hoo= document.getElementById(hoo) || '';
return (hoo.nodeType== 1)? hoo:null;
}
window.onload= function(){
Numword.display= function(){
var who= mr('strum_in'), v= who.value.trim(),
v2, nw, n2, p2, w= '';
if(!/(\d|Infinity)/i.test(v)) return;
if(/^\.\d/.test(v)) v= '0'+v;
if(/[$.\/eE-]/.test(v)){
mr('ord_cbx').checked= false;
}
nw= Numword.getWords(v)+'';
if(nw){
if(mr('ord_cbx').checked) nw= nw.ordinal();
Run.doc('p_bf', 'numword_div', '', v+'= '+nw);
}
who.value= '';
mr('strum_in').focus()
}
Numword.sampler= function(){
mr('ord_cbx').checked= false;
var doc= Run.doc, A,B,C;
A= ['150', '0.12', '65.35', '$65.45', '2012', '98.6', '897456971.25',
'1 1/2', '12 and 3/4', '-9', '33 and 1/3','12:15','09:30',
'1.155e+17', '1.222e3', '4.5e-10', '3.125e-3'].map(function(itm){
return itm+'= '+Numword.getWords(itm);
});
B= [1, 2, 3, 21, 28, 112].map(function(itm){
return itm+ '= '+itm.toWords().ordinal();
});
B.unshift('Ordinal format:');
A= A.concat(B);
Run.zap('numword_div');
A.forEach(function(itm){
p2= doc('p', 'numword_div', '',itm);
});
mr('strum_in').focus()
}
mr('toWordsBtn').onclick= Numword.display;
mr('demoWordsBtn').onclick= Numword.sampler;
mr('clearWordsBtn').onclick= function(){
Run.zap('numword_div');
mr('strum_in').focus();
};
setTimeout(function(){
mr('strum_in').focus();
},
100);
}
</script>
</head>
<body>
<div id= "numstringDiv">
<h1> Numbers to Words<br>
<span> US- English version</span> </h1>
<div style= "max-width:900px; font-family:Georgia, 'Times New Roman',serif;">
<p> Besides digits, numerical input can include a negative sign(-50), dollar sign ($50.25),
decimal point (.), exponential (1.15e+25) or a real number with a division slash (1/2 or 9 3/4).</p>
<p> If you are expressing a positive integer you can return an ordinal number-
that is, 21 converts to "twenty first" and 12 to "twelfth".</p>
</p>
<p id= " "> Use the "Demo" button for some examples.</p>
</div>
<h3 style= "margin-top: 1em;"> Enter a number to convert to words</h3>
<div>
<label> Ordinal:<input id= "ord_cbx" type= "checkbox"> </label>
<input autocomplete= "off" size= "40" id= "strum_in" type= "text">
<button id= "toWordsBtn" type= "button" style= "margin-left: 1em;"> Convert</button>
<button type= "button" id= "demoWordsBtn"> Demo</button>
<button id= "clearWordsBtn" type= "button"> Clear</button>
</div>
<div style= "font-weight: bold;" id= "numword_div">
</div>
</div>
</body>
</html>