Prev: FYI: Creating circular references is a perfectly OK thing todo.
Next: FAQ Topic - How do I format a Number as a String with exactly2 decimal places? (2010-07-28)
From: FAQ server on 27 Jul 2010 19:00 ----------------------------------------------------------------------- FAQ Topic - How do I format a Number as a String with exactly 2 decimal places? ----------------------------------------------------------------------- When formatting money for example, to format 6.57634 to 6.58, 6.7 to 6.50, and 6 to 6.00? Rounding of x.xx5 is unreliable, as most numbers are not represented exactly. See also: Why does simple decimal arithmetic give strange results? [ref 1] The statement `n = Math.round(n * 100)/100` converts `n` to a `Number` value close to a multiple of `0.01`. However, there are some problems. Converting the number to a string `(n + "")`, does not give trailing zeroes. Rounding numbers that are very close to `x.5`, for example, `Math.round(0.49999999999999992)` results `1`. ECMA-262 3rd Edition introduced `Number.prototype.toFixed`. There are bugs in JScript's implementation with certain numbers, for example `0.07`. var numberToFixed = (function() { return toFixedString; function toFixedString(n, digits) { var unsigned = toUnsignedString(Math.abs(n), digits); return (n < 0 ? "-" : "") + unsigned; } function toUnsignedString(m, digits) { var t, s = Math.round(m * Math.pow(10, digits)) + "", start, end; if (/\D/.test(s)) { return "" + m; } s = padLeft(s, 1 + digits, "0"); start = s.substring(0, t = (s.length - digits)); end = s.substring(t); if(end) { end = "." + end; } return start + end; // avoid "0." } /** * @param {string} input: input value converted to string. * @param {number} size: desired length of output. * @param {string} ch: single character to prefix to s. */ function padLeft(input, size, ch) { var s = input + ""; while(s.length < size) { s = ch + s; } return s; } })(); // Test results document.writeln([ "numberToFixed(9e-3, 12) => " + numberToFixed(9e-3, 12), "numberToFixed(1.255, 2) => " + numberToFixed(1.255, 2), "numberToFixed(1.355, 2) => " + numberToFixed(1.355, 2), "numberToFixed(0.1255, 3) => " + numberToFixed(0.1255, 3), "numberToFixed(0.07, 2) => " + numberToFixed(0.07, 2), "numberToFixed(0.0000000006, 1) => " + numberToFixed(0.0000000006, 1), "numberToFixed(0.0000000006, 0) => " + numberToFixed(0.0000000006, 0) ].join("\n")); <URL: http://www.merlyn.demon.co.uk/js-round.htm> <URL: http://msdn.microsoft.com/en-us/library/sstyff0z%28VS.85%29.aspx> References: ----------- [1] http://jibbering.com/faq/#binaryNumbers The complete comp.lang.javascript FAQ is at http://jibbering.com/faq/ -- The sendings of these daily posts are proficiently hosted by http://www.pair.com.
From: Ry Nohryb on 27 Jul 2010 19:24 On Jul 28, 1:00 am, "FAQ server" <javascr...(a)dotinternet.be> wrote: > ----------------------------------------------------------------------- > FAQ Topic - How do I format a Number as a String with > exactly 2 decimal places? > ----------------------------------------------------------------------- > (...) This is the problem. JavaScript coding style bent to suit IE's bugs. NO, please, no. The proper way to do this is : (number).toFixed(decimalPlaces) --> string For example: Math.PI.toFixed(3) "3.142" or (6).toFixed(2) --> "6.00" That's what ought to come FIRST in this FAQ entry, and it should be the recommended way of doing it. Then, -*only*after*having*said*that*in*the*first*place*-, you can also say that IEs have got (yet another) bug that affects Number.prototype.toFixed(), sooo, in IEs you could do instead: (blah, blah, blah) -- Jorge.
From: David Mark on 28 Jul 2010 23:16 On Jul 28, 12:16 pm, kangax <kan...(a)gmail.com> wrote: > On 7/27/10 7:24 PM, Ry Nohryb wrote: > > > > > > > On Jul 28, 1:00 am, "FAQ server"<javascr...(a)dotinternet.be> wrote: > >> ----------------------------------------------------------------------- > >> FAQ Topic - How do I format a Number as a String with > >> exactly 2 decimal places? > >> ----------------------------------------------------------------------- > >> (...) > > > This is the problem. JavaScript coding style bent to suit IE's bugs. > > NO, please, no. The proper way to do this is : > > > (number).toFixed(decimalPlaces) --> string > > > For example: > > > Math.PI.toFixed(3) > > "3.142" > > > or > > > (6).toFixed(2) > > --> "6.00" > > > That's what ought to come FIRST in this FAQ entry, and it should be > > the recommended way of doing it. > > > Then, -*only*after*having*said*that*in*the*first*place*-, you can also > > say that IEs have got (yet another) bug that affects > > Number.prototype.toFixed(), sooo, in IEs you could do instead: > > > (blah, blah, blah) > > Does `numberToFixed` from the FAQ entry solve anything that fully > compliant `Number.prototype.toFixed` doesn't? From what I can see, they > should be identical. Haven't looked at it. Will check when I have a chance. > > If they are, then why not employ a feature test and skip workaround once > implementation is determined to be compliant? At least for performance > reasons. > I've got one here somewhere. In my branch of Dojo I think (replaced a UA sniff for IE). :)
From: Dr J R Stockton on 29 Jul 2010 16:03 In comp.lang.javascript message <4c4f64f9$0$279$14726298(a)news.sunsite.dk >, Tue, 27 Jul 2010 23:00:03, FAQ server <javascript(a)dotinternet.be> posted: >FAQ Topic - How do I format a Number as a String with >exactly 2 decimal places? >ECMA-262 3rd Edition introduced `Number.prototype.toFixed`. >There are bugs in JScript's implementation with certain numbers, >for example `0.07`. No, there is no bug with toFixed formatting 0.07 as per Subject. 0.07.toFixed(2) -> '0.07' You have been told, more than once IIRC, and have agreed at least once, that the example should be 0.007 or similar. NOW is the time to make the correction. There is, in addition, a bug in Opera's toPrecision : 0.1230.toPrecision(4) -> 0.123 // should be 0.1230 >function toFixedString(n, digits) { >var unsigned = toUnsignedString(Math.abs(n), digits); >return (n < 0 ? "-" : "") + unsigned; >} That will not give the correct sign for n == -0 . In the FAQ, sign should be given by a function such as function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " } Readers can more easily simplify that where needed than they can add to the simplistic form in the FAQ. There should also be a mention of testing the sign of (X+1/X). -- (c) John Stockton, nr London UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME. Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links. Proper <= 4-line sig. separator as above, a line exactly "-- " (RFCs 5536/7) Do not Mail News to me. Before a reply, quote with ">" or "> " (RFCs 5536/7)
From: David Mark on 29 Jul 2010 18:53
On Jul 29, 3:57 pm, Dr J R Stockton <reply1...(a)merlyn.demon.co.uk> wrote: > In comp.lang.javascript message <k-idncXl5612ys3RnZ2dnUVZ_rqdnZ2d(a)gigane > ws.com>, Wed, 28 Jul 2010 12:16:43, kangax <kan...(a)gmail.com> posted: > > >Does `numberToFixed` from the FAQ entry solve anything that fully > >compliant `Number.prototype.toFixed` doesn't? From what I can see, they > >should be identical. > > In FF 3.0.19 and IE8, (-0).toFixed(2) wrongly gives '0.00'. The code in > the FAQ could be corrected to fix that too. > > >If they are, then why not employ a feature test and skip workaround > >once implementation is determined to be compliant? At least for > >performance reasons. > > Using a feature test means that the code must be tested in at least two > browsers. It means that more code must be downloaded. > > And, considering the likely usage as being for display (or for writing > to file with WSH JScript), does speed matter? > > Doing StrS(Math.PI, 3, 5) on this machine takes under 24 us in FireFox, > and StrS is similar to the FAQ code; doing Math.PI.toFixed(5) takes > under 4 us. Will that 20 us difference matter significantly often? As always, it depends on the context. That's one of the problems inherent to writing GP code. |