R
Ry Nohryb
This test is not enough now, meseems:
a = '12345abc.5def'
document.write((a.toFP(10)) // 12345.0005
use:
var re = base>10 ?'a-'+String.fromCharCode(86+base) :'';
re = new RegExp('[^0-9'+re+'\.+-]','i');
if (re.test(this)) return NaN;
and add:
if (/[+-]/.test(this.substr(1))) return NaN; //+- must be in position 0
if (this.replace(/[^\.]+/g,'').length>1) return NaN; // count of . <=1
Well, yes, the inputs ought to be validated. Both the base parameter
and the 'this' string.
Funny thing is that once you add the -ugly- regExp to test the
structure and its contents, it's easy to use it to capture the
validated parts, and then the rest becomes even simpler than before
( ~8 LOC ):
String.prototype.toFP= function (base, n, r, w, div) {
//20100531 by (e-mail address removed)
/* check that base is in range and an integer */
if ((base < 2) || (base > 36) || (base % 1)) return NaN;
/* get the digits that are valid for this base */
validDigits= "0123456789abcdefghijklmnopqrstuvwxyz".substr(0, base);
/* validate structure and contents of the input str : */
/* ^ (optional) whitespace + (optional) a single char [-+] */
/* + (non-optional) 1 or more validDigits + (optional) a point */
/* + (optional) more validDigits + (optional) whitespace $ */
n= "^\\s{0,}([-+]{0,1})(["+ validDigits+ "]{1,})[.]{0,1}(["+
validDigits+ "]{0,})\\s{0,}$";
/* exec n on 'this' now, case-insensitively, and reuse n*/
if (!(n= new RegExp(n, "i").exec(this))) return NaN;
/* got captured : */
/* n[1]= sign, n[2]=integer part, n[3]= fractional part */
if (isFinite(r= parseInt(n[2], base)) && (w= n[3].length)) {
/* trim until div is finite */
while (!isFinite(div= Math.pow(base, w))) w--;
r+= parseInt(n[3].substr(0, w), base)/ div;
}
/* sign is one of "1" or "+1" or "-1" */
return (n[1]+ "1")* r;
};