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 2 Jun 2010 09:57 Dr J R Stockton wrote on 01 jun 2010 in comp.lang.javascript: > Query : what does one call the dot in 123.456 if the radix is unknown? A dot? [In your above example, rhe radix is only partly unknown, as it must be between 7 and 36 inclusive.] A fraction delimiter? [this is better, as there is no unanimity about what character should be used.] -- Evertjan. The Netherlands. (Please change the x'es to dots in my emailaddress)
From: Scott Sauyet on 2 Jun 2010 10:08 Ry Nohryb wrote: > Scott Sauyet wrote: >> Ry Nohryb wrote: >>> [ ... ] >> If I find some time this evening, I'll look into the accuracy. I'm glad you had a chance to investigate, because I will not have the time before the weekend. >> [ ... ] >> parseFraction = function(str, base) { >> if (!str) return 0; >> var digits = str.split(""), total = 0; >> for (var i = digits.length; i--;) { >> total += allDigits.indexOf(digits[i]); >> total /= base; >> } >> return total; >> }; >> [ ... ] > I like that parseFraction() of yours, it's awesome. Good idea. Thanks. I'm not sure if it has any practical advantages, but it's at least fairly clear mathematically. > In > order to test it agains the .toFP algorithm, I've written this: it > loops through all the bases, and converts an increasingly smaller > number i until i !=== [ parseFloat || toFP ](i.toString(base)). The > win is given to the algorithm that fails with a smaller i. The funny > thing is that different browsers give different results (due, I guess, > to differences in .toString(base)), but, in general, your algorithm > WINS (in all but FF): It's an interesting result, but I'm not sure how much that really tells us about accuracy. It's also not clear to me if floating point --> string --> floating point is as good a test as string --> floating point --> string It's right now just a gut feeling, and I'm not sure why, but I think we'd learn more from the latter. >>> Would it be a good idea to memoize the regExps ? > >> If you're concerned about performance, then yes. They depend only on >> the (35 possible) bases used. > > Well done. toFP() now memoizes them too :-) For your function, you might want to cache the "w" values as well. -- Scott
From: Thomas 'PointedEars' Lahn on 2 Jun 2010 12:53 Scott Sauyet wrote: > Ry Nohryb wrote: >> Scott Sauyet wrote: >>> [ ... ] >>> parseFraction = function(str, base) { >>> if (!str) return 0; >>> var digits = str.split(""), total = 0; >>> for (var i = digits.length; i--;) { >>> total += allDigits.indexOf(digits[i]); >>> total /= base; >>> } >>> return total; >>> }; >>> [ ... ] > >> I like that parseFraction() of yours, it's awesome. Good idea. > > Thanks. I'm not sure if it has any practical advantages, but it's at > least fairly clear mathematically. It is clear(er), but it is unfortunately not mathematically sound because we are dealing with *floating-point* arithmetics here, where precision is limited (as I indicated in one of first replies to Jorge): var b = 3, e = 4; x = Math.pow(b, e), y = Math.pow(b, e + 1); /* * JavaScript 1.8.2: * 0.004115226337448559 0.00411522633744856 false */ console.log(1/x/b, 1/y, 1/x/b == 1/y); PointedEars -- Use any version of Microsoft Frontpage to create your site. (This won't prevent people from viewing your source, but no one will want to steal it.) -- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)
From: Scott Sauyet on 2 Jun 2010 15:03 Thomas 'PointedEars' Lahn wrote: >Scott Sauyet wrote: >> Ry Nohryb wrote: >>> Scott Sauyet wrote: >>>> [ ... ] (I should have included this line:) | var allDigits = "0123456789abcdefghijklmnopqrstuvwxyz", >>>> parseFraction = function(str, base) { >>>> if (!str) return 0; >>>> var digits = str.split(""), total = 0; >>>> for (var i = digits.length; i--;) { >>>> total += allDigits.indexOf(digits[i]); >>>> total /= base; >>>> } >>>> return total; >>>> }; >>>> [ ... ] > >>> I like that parseFraction() of yours, it's awesome. Good idea. > >> Thanks. I'm not sure if it has any practical advantages, but it's at >> least fairly clear mathematically. > > It is clear(er), but it is unfortunately not mathematically sound because we > are dealing with *floating-point* arithmetics here, where precision is > limited [ ... ] > [ example elided ] Yes, I understand that we are dealing with an implementation of IEEE-754. But I don't see how that makes my algorithm mathematically unsound. It is certainly not as efficient as the one you used, but I think it might avoid some rounding issues. For instance, if parseFloat1 is the function you posted earlier [1] and parseFloat2 is the one I posted [2], then in JavaScript 1.8.2 parseFloat1("0.r3j6f0mqo4fr3j6f0m", 36).toString(36) yields "0.r3j6f0mqo3m", whereas parseFloat2("0.r3j6f0mqo4fr3j6f0m", 36).toString(36)) yields "0.r3j6f0mqo4f", clearly a better approximation. This approach, though sacrifices the speed of your algorithm. I haven't done any performance tests, but if you were to alter your function to cache the results of the regular expressions, I would guess that your code would run significantly faster than mine -- maybe not a full order of magnitude, but several times faster, I would imagine. [1] <news:4430313.MhkbZ0Pkbq(a)PointedEars.de> [2] <news:4c7655c5- e83f-4559-89f5-5a8ebe279e46(a)q23g2000vba.googlegroups.com> -- Scott
From: Thomas 'PointedEars' Lahn on 2 Jun 2010 16:55
Scott Sauyet wrote: > Thomas 'PointedEars' Lahn wrote: >> Scott Sauyet wrote: >>> Ry Nohryb wrote: >>>> Scott Sauyet wrote: >>>>> [ ... ] > (I should have included this line:) > | var allDigits = "0123456789abcdefghijklmnopqrstuvwxyz", >>>>> parseFraction = function(str, base) { >>>>> if (!str) return 0; >>>>> var digits = str.split(""), total = 0; >>>>> for (var i = digits.length; i--;) { >>>>> total += allDigits.indexOf(digits[i]); >>>>> total /= base; >>>>> } >>>>> return total; >>>>> }; >>>>> [ ... ] >>>> I like that parseFraction() of yours, it's awesome. Good idea. >>> Thanks. I'm not sure if it has any practical advantages, but it's at >>> least fairly clear mathematically. >> >> It is clear(er), but it is unfortunately not mathematically sound because >> we are dealing with *floating-point* arithmetics here, where precision is >> limited [ ... ] >> [ example elided ] > > Yes, I understand that we are dealing with an implementation of > IEEE-754. But I don't see how that makes my algorithm mathematically > unsound. It is certainly not as efficient as the one you used, but I > think it might avoid some rounding issues. You are doing *more* floating-point operations, how can you have *less* rounding issues? > For instance, if parseFloat1 is the function you posted earlier [1] > and parseFloat2 is the one I posted [2], then in JavaScript 1.8.2 > > parseFloat1("0.r3j6f0mqo4fr3j6f0m", 36).toString(36) > > yields "0.r3j6f0mqo3m", whereas > > parseFloat2("0.r3j6f0mqo4fr3j6f0m", 36).toString(36)) > > yields "0.r3j6f0mqo4f", clearly a better approximation. No doubt about that, although I think you have the test case backwards. I have since tested my approach more thoroughly and accepted that {1,198} is flawed as it sacrifices too much precision. You need to compare the return value of yours against one of Jorge's that works (that in <99e57eb6-f5c7-410e-a40f-07ae48af2a3d(a)b21g2000vbh.googlegroups.com> returns NaN with your test case in JavaScript 1.8.2) instead. PointedEars -- Danny Goodman's books are out of date and teach practices that are positively harmful for cross-browser scripting. -- Richard Cornford, cljs, <cife6q$253$1$8300dec7(a)news.demon.co.uk> (2004) |