Prev: Firefox cache issue
Next: FAQ Topic - How do I format a Number as a String with exactly 2 decimal places? (2010-05-27)
From: Evertjan. on 27 May 2010 09:49 Ry Nohryb wrote on 27 mei 2010 in comp.lang.javascript: > String.prototype.toFP= function (base, digits, r, w, n) { > digits= "0123456789abcdefghijklmnopqrstuvwxyz", r= 0; > w= (n= this.toLowerCase().split('.'))[0].length; > n.join('').split('').forEach(function (s) { > r+= digits.indexOf(s) * Math.pow(base, --w) }); > return r; >}; > Nice! since all non-'digit' chars would count as -1, I would test for that, as that makes debugging extreemly difficult. String.prototype.toFP= function (base, digits, r, w, n) { if (/[^0-9a-z\.]/i.test(this)) return NaN; // <<<--- digits= "0123456789abcdefghijklmnopqrstuvwxyz", r= 0; w= (n= this.toLowerCase().split('.'))[0].length; n.join('').split('').forEach(function (s) { r+= digits.indexOf(s) * Math.pow(base, --w) }); return r; }; -- Evertjan. The Netherlands. (Please change the x'es to dots in my emailaddress)
From: Ry Nohryb on 27 May 2010 10:25 On May 27, 3:49 pm, "Evertjan." <exjxw.hannivo...(a)interxnl.net> wrote: > > Nice! > > since all non-'digit' chars would count as -1, > I would test for that, > as that makes debugging extreemly difficult. > > String.prototype.toFP= function (base, digits, r, w, n) { > if (/[^0-9a-z\.]/i.test(this)) return NaN; // <<<--- > digits= "0123456789abcdefghijklmnopqrstuvwxyz", r= 0; > w= (n= this.toLowerCase().split('.'))[0].length; > n.join('').split('').forEach(function (s) { > r+= digits.indexOf(s) * Math.pow(base, --w) }); > return r; > }; Yes, good idea. And instead of n.join('').split('').forEach(f) an [].forEach.call(n.join(''), f)... might be faster: String.prototype.toFP= function (base, digits, w, n, r) { if (/[^0-9a-z\.]/i.test(this)) return NaN; digits= "0123456789abcdefghijklmnopqrstuvwxyz"; w= (n= this.toLowerCase().split('.'))[r= 0].length; n.forEach.call(n.join(''), function (s) { r+= digits.indexOf(s) * Math.pow(base, --w) }); return r; }; What do we do with the sign ? -- Jorge.
From: Evertjan. on 27 May 2010 14:16 Ry Nohryb wrote on 27 mei 2010 in comp.lang.javascript: > On May 27, 3:49�pm, "Evertjan." <exjxw.hannivo...(a)interxnl.net> wrote: >> >> Nice! >> >> since all non-'digit' chars would count as -1, >> I would test for that, >> as that makes debugging extreemly difficult. >> >> String.prototype.toFP= function (base, digits, r, w, n) { >> � if (/[^0-9a-z\.]/i.test(this)) return NaN; // <<<--- >> � digits= "0123456789abcdefghijklmnopqrstuvwxyz", r= 0; >> � w= (n= this.toLowerCase().split('.'))[0].length; >> � n.join('').split('').forEach(function (s) { >> � � r+= digits.indexOf(s) * Math.pow(base, --w) }); >> � return r; >> }; > > Yes, good idea. And instead of n.join('').split('').forEach(f) an > [].forEach.call(n.join(''), f)... might be faster: > > String.prototype.toFP= function (base, digits, w, n, r) { > if (/[^0-9a-z\.]/i.test(this)) return NaN; > digits= "0123456789abcdefghijklmnopqrstuvwxyz"; > w= (n= this.toLowerCase().split('.'))[r= 0].length; > n.forEach.call(n.join(''), function (s) { > r+= digits.indexOf(s) * Math.pow(base, --w) }); > return r; >}; > > What do we do with the sign ? this2 = this; minus = 1; if (this2.substr(0,1)=='-') { this2 = this2.substr(1); // or .slice()? minus = -1; }; ..........this2......... return minus*r; -- Evertjan. The Netherlands. (Please change the x'es to dots in my emailaddress)
From: Thomas 'PointedEars' Lahn on 27 May 2010 17:07 Dr J R Stockton wrote: > Some may not have noted that Number.toString(16) handles non-integers. > Math.PI.toString(16) -> 3.243f6a8885a3 > 1e44.toString(16) -> 47bf19673df53000000000000000000000000 > Math.random().toString(2) => 0 . /[01]{1,53}/ > > ECMA 262 (5) 15.7.4.2 Number.prototype.toString ( [ radix ] ) > makes no mention of non-integers. It does not have to mention non-integers as all Number values are internally represented as IEEE-754 double-precision floating-point values, which by definition includes non-integers. | If radix not present or is undefined the Number 10 is used as the value of | radix. If ToInteger(radix) is the Number 10 then this Number value is | given as an argument to the ToString abstract operation; the resulting | String value is returned. | | [...] | If ToInteger(radix) is an integer from 2 to 36, but not 10, the result is | a String representation of this Number value using the specified radix. | Letters a-z are used for digits with values 10 through 35. The precise | algorithm is implementation-dependent if the radix is not 10, however the | algorithm should be a generalization of that specified in 9.8.1. > A Hex integer string H can be turned into a Number by > + ( "0x" + H ) Or simply parseInt(H, 16). > but that does not work for a Hex fraction string. Is there in fact an > easy built-in way of converting non-integer Hex strings to Number? No, I don't think so. Obviously you could do this: var s = "f.0c"; var f = (s.match(/\.([\da-f]+)/i) || [, "0"])[1]; /* 15.046875 = 15 + 12 * Math.pow(16, -2) */ var n = parseInt(s, 16) + parseInt(f, 16) / Math.pow(16, f.length); > Otherwise, I suggest that ECMA 6 should specify a Method whereby for ANY > Number X the result of X.toString(B) can be converted to the original X > (disregarding the sign of zero). It would suffice if parseFloat() could take a second argument to specify the base, as does parseInt(). But while it would be good to have it specified in _ECMAScript Ed._ 6 ("Harmony"), I do not think we really need ES6 (and probably to wait another 10 years) for that. It could, for example, be implemented in JavaScript 1.9 as can be expected from Firefox 4.0, and then, through competition, copied by other implementations like so many other features before. PointedEars -- var bugRiddenCrashPronePieceOfJunk = ( navigator.userAgent.indexOf('MSIE 5') != -1 && navigator.userAgent.indexOf('Mac') != -1 ) // Plone, register_function.js:16
From: Ry Nohryb on 28 May 2010 07:34
On May 27, 11:07 pm, Thomas 'PointedEars' Lahn <PointedE...(a)web.de> wrote: > (...) > var s = "f.0c"; > var f = (s.match(/\.([\da-f]+)/i) || [, "0"])[1]; > > /* 15.046875 = 15 + 12 * Math.pow(16, -2) */ > var n = parseInt(s, 16) + parseInt(f, 16) / Math.pow(16, f.length); > (...) We're almost there, but not yet: function pointyParseFloat (s, base) { var f = (s.match(/\.([\da-f]+)/i) || [, "0"])[1]; return parseInt(s, base) + parseInt(f, base) / Math.pow(base, f.length); } pointyParseFloat(Math.PI.toString(16), 16) --> 3.141592653589793 pointyParseFloat(Math.PI.toString(33), 33) --> 3.121212121212121 pointyParseFloat((-Math.PI).toString(16), 16) --> -2.858407346410207 String.prototype.toFP= function (base, digits, w, n, r) { if (/[^0-9a-z\.]/i.test(this)) return NaN; digits= "0123456789abcdefghijklmnopqrstuvwxyz"; r= parseInt((n= this.toLowerCase().split('.'))[w= 0], base); n.forEach.call(n[1], function (s) { r+= digits.indexOf(s) * Math.pow(base, --w) }); return r; }; (Math.PI).toString(16).toFP(16) --> 3.141592653589793 (Math.PI).toString(33).toFP(33) --> 3.141592653589793 (-Math.PI).toString(33).toFP(33) --> NaN -- Jorge. |