467,150 Members | 1,167 Online

# <faqentry>How do I convert a Number into a String with exactly 2 decimal places?</faqentry>

 [The original thread is more than one month old - this may pose problem for posting over some news servers. This is why I'm starting a new one] I'd still like to finish this rounding mess. As a startup lemma we can take that VK is the worst programmer of all times and places: let's move from here forward please. The usability of any program depends on exact behavior description. This way it is a must to know i) what argument we can feed into and ii) what results to expect. The usability of the current FAQ code in this aspect is zero. "take power of x, extract y" and similar is not a behavior description - it is a description of the formal algorithm. It is the same as instead remote control manual provide a detailed electronic schema of the control. Obviously a reference to some other formal algorithm ("in accordance with ECMA-262 section...") doesn't add any usability. So first it has to be defined what common rules (behavior) are used for rounding. The key points are: 1) how to round with losses (when some signs have to be dropped) 2) how to round equipoint (in decimal system it will be 5) 3) how to round negative As milestone values used everywhere further are 1) 1.033 2) 1.035 3) -1.035 IEEE-754/IEEE-754r define five methods of rounding for numeral string representation: (the specification order is changed, the implemented methods moved atop) 1) Biased round to nearest, ties away from zero Implemented by IE's toFixed method. Overall the most known as studied at the school toFixed(2) 1.033 = 1.03 1.035 = 1.04 (equipoint ties away zero, so to positive infinity for positive values) -1.035 =-1.04 (equipoint ties away zero, so to negative infinity for negative values) 2) Biased towards zero Implemented by Gecko and Opera toFixed method. toFixed(2) 1.033 = 1.03 1.035 = 1.03 (equipoint ties towards zero) -1.035 =-1.03 (equipoint ties towards zero) 3) Biased towards positive infinity No known ECMAScript implementations (?) toFixed(2) 1.033 = 1.03 1.035 = 1.04 (equipoint ties towards positive infinity) -1.035 =-1.03 (equipoint ties towards positive infinity) 4) Biased towards negative infinity No known ECMAScript implementations (?) toFixed(2) 1.033 = 1.03 1.035 = 1.03 (equipoint ties towards negative infinity) -1.035 =-1.04 (equipoint ties towards negative infinity) This is as far as IEEE-754 currently goes. As it was pointed by some posters, rounding is not some "natural" feature coming out of numbers themselves. It is merely a contract behavior: "let's make it as this...". This way it can be a rule combining two or more rules from IEEE or even all separate custom algorithm. In the latter case of course any appellations to "standards" and "bug fixes" must be dropped. In any case exact behavior description has to be given. This way I am insistently asking to explain what rounding rule is considered correct by FAQ maintainer: 1) Biased round to nearest, ties away from zero (IE) - thus Gecko needs a fix 2) Biased towards zero (Gecko, Opera) - thus IE needs a fix 3) some third - thus everyone needs a fix In the 3rd case what this rounding rule is? Jan 28 '07 #1
• viewed: 3176
Share:
19 Replies
 On Jan 28, 11:30 pm, "Richard Cornford" wrote: As milestone values used everywhere further are 1) 1.033 2) 1.035 3) -1.035 So you have still not understood that javascript's numeric type cannot represent certain numbers, so instead it uses a number that is the nearest approximation of the original number that it can represent. As I once asked prior: please be nasty, sarcastic and so on - but please don't be silly. The choice of the "nearest approximation" for these three numbers (can be any other triplet of course) defines the rounding mechanics in use. I spelled all four from IEEE-754, I explained which one is chosen by IE and by Gecko. Now I'm asking which one of four should be _really_ used by "selected people"'s opinion. If no one but something fifth then please spell it. If the IEEE official terms put too much of challenge then simply give the rounding results with two numerals after comma which are considered correct by you: correctToFixed(2) 1.033 =? 1.035 =? -1.035 =? This would easily show what rounding method are you bearing in your mind. Jan 28 '07 #3
 Richard Cornford wrote: > >If the IEEE official terms put too much of challengethen simply give the rounding results with two numeralsafter comma which are considered correct by you:correctToFixed(2)1.033 =?1.035 =?-1.035 =? Are you asking which results the - toFixed - method of Number objects would return? There is a specified algorithm for - toFixed -, so its correct output is output that would be produced by applying the algorithm to the input. On the other hand, as you have repeatedly been told, there is no value of the numeric type in javascript that precisely represents 1.035, and so that value _can_not_ be the input value for the - toFixed - algorithm. VK, Just try to imagine how many bits you have to store a piece of information, when thinking about precision and representation and what it means. You can only store 256 values in 8 bits. Clear, isn't it? Same goes for floating points. If you have 4 bytes, or 8, or whatever, to store a floating point number, is should be clear you cannot store ANY floating point number excactly in it. Some rounding is always needed. The amount of rounding (=error when storing floating point numbers) depends on the number of bytes allocated to a variable, but since you don't have an unlimitted amount of bytes available, you will always have rounding in the real world. So if you are talking about 1.035 and want to store that in a variable, wonder how much bytes JavaScript has to represent the number. A simple example: var val1 = 1.12345; var val2 = 1.123456; var val3 = (val1-val2); alert (val3); This might be a good startingpoint to get an idea of what Richard is reffering to: http://en.wikipedia.org/wiki/Round-off_error http://en.wikipedia.org/wiki/Machine_epsilon http://en.wikipedia.org/wiki/Floating_point_arithmetic Regards, Erwin Moller Jan 29 '07 #5
 On Jan 29, 2:01 am, "Richard Cornford" wrote: If the IEEE official terms put too much of challenge then simply give the rounding results with two numerals after comma which are considered correct by you: correctToFixed(2) 1.033 =? 1.035 =? -1.035 =? Are you asking which results the - toFixed - method of Number objects would return? There is a specified algorithm for - toFixed -, so its correct output is output that would be produced by applying the algorithm to the input. That was my original suspicion, thank you for confirming it and it's good I decided to take care of this FAQ. So basically the position is: "We don't know what rounding results will be produced for a particular number - until it's actually rounded. But whatever rounding result will be - it will be the correct one, and anything else wrong". 3-4 years ago I would decide that I'm talking with a mentally inadequate person, but now I accustomed a bit to clj regulars' specifics. Still you had to make some rounding testing I guess to conclude that native toFixed on say IE or Gecko do not "predict the feature" in the same way as your algorithm does. What was these series? Of course you may add some fun by stating that the current algorithm is so correct that anything else is wrong by definition without any extra testing needed. P.S. The current rounding question is based on the common default of people lacking any real knowledge but pretending to have such by quickly reading some serious sources. Usually they miss the whole picture but fixate on one or two points they managed to understand. In this case you grabbed the internal unbiased round to nearest ties to even rule. In my post I said "five rounding rules" but I named only four and I was waiting you ask for the fifth. Here is it: the default internal unbiased round to nearest ties to even. It was not listed as an option because it is internal - you cannot get on it unless gaining system level access to the engine or unless making the entire calculation on BigMath (with string values). "5 is uncertain" you are repeating - but not grasping its real sense - is from there. On equipoint resolution the system will move to the nearest even, with overall destribution 50/50 But again it is internal mechanics you have no access nor business. P.P.S. As it is pretty much confirmed that no one can tell what rounding rule is the most "ECMAScript correct" I guess that biased ties away from zero will be the such, as I initially decided. It is the most publically known and the most implemented in javascript engines (IE, 85%-95% of visitors). Jan 29 '07 #6
 On Jan 29, 2:23 pm, Erwin Moller So if you are talking about 1.035 and want to store that in a variable, wonder how much bytes JavaScript has to represent the number. A simple example: var val1 = 1.12345; var val2 = 1.123456; var val3 = (val1-val2); alert (val3); This might be a good startingpoint to get an idea of what Richard is reffering to: Erwin, the FAQ in question is "How do I convert a Number into a String with exactly 2 decimal places?" - this is the startingpoint. There are 4 official rules for that, we can come with 5th, 6th etc. - as long as it provides predictable results. The limitations of IEEE-754 floating point are known to me better then Richard could imagine. Unfortunately fixed point systems on current 32- bit machines impose too narrow range of numbers to be universally usable. IEEE-754 floating point still remains as the most usable compromise for PCs (personal computers). But internal unbiased rounding algorithm of IEEE-754 based systems is irrelevant to this FAQ. Yes, we cannot represent exactly 2^52+1, 1/3, PI etc. etc. But we have to say exactly what will be 1.035 or -1.035 converted into a string with exactly 2 decimal places after comma. All four official rules are giving exact answer on it. Both IE and Geck toFixed give the exact answer as well: but they are using different rules so these answers will be different. So the task is to decide who is right: IE, Gecko, no one; based on this decision a program has to be provided to ensure unifirmed results by fixing IE, or Gecko or both. Jan 29 '07 #7
 VK wrote: On Jan 29, 2:23 pm, Erwin Moller >So if you are talking about 1.035 and want to store that in a variable,wonder how much bytes JavaScript has to represent the number.A simple example:var val1 = 1.12345;var val2 = 1.123456;var val3 = (val1-val2);alert (val3);This might be a good startingpoint to get an idea of what Richard isreffering to: Erwin, the FAQ in question is "How do I convert a Number into a String with exactly 2 decimal places?" - this is the startingpoint. There are 4 official rules for that, we can come with 5th, 6th etc. - as long as it provides predictable results. The limitations of IEEE-754 floating point are known to me better then Richard could imagine. Unfortunately fixed point systems on current 32- bit machines impose too narrow range of numbers to be universally usable. IEEE-754 floating point still remains as the most usable compromise for PCs (personal computers). But internal unbiased rounding algorithm of IEEE-754 based systems is irrelevant to this FAQ. Yes, we cannot represent exactly 2^52+1, 1/3, PI etc. etc. But we have to say exactly what will be 1.035 or -1.035 converted into a string with exactly 2 decimal places after comma. All four official rules are giving exact answer on it. Both IE and Geck toFixed give the exact answer as well: but they are using different rules so these answers will be different. So the task is to decide who is right: IE, Gecko, no one; based on this decision a program has to be provided to ensure unifirmed results by fixing IE, or Gecko or both. Ok VK, I happened to be reading that piece on wikipedia, and thought it might be relevant to the discussion. But if you all know it allready, I better shut up. :-) Regards, Erwin Moller Jan 29 '07 #8
 On Jan 29, 3:21 pm, Erwin Moller I happened to be reading that piece on wikipedia, and thought it might be relevant to the discussion. But if you all know it allready, I better shut up. :-) Why? It is a public discussion - anyone's opinion is welcome. Say what would you personally expect from 1.035.toFixed(2) : 1.03 (Gecko) or 1.04 (IE) ? And from -1.035.toFixed(2) : -1.03 or -1.04 Either is "correct" - thus in accordance with one of official rounding rules - but what would you expect first? Jan 29 '07 #9
 VK wrote: On Jan 29, 2:23 pm, Erwin Moller >So if you are talking about 1.035 and want to store that in a variable,wonder how much bytes JavaScript has to represent the number.A simple example:var val1 = 1.12345;var val2 = 1.123456;var val3 = (val1-val2);alert (val3);This might be a good startingpoint to get an idea of what Richard isreffering to: Erwin, the FAQ in question is "How do I convert a Number into a String with exactly 2 decimal places?" - this is the startingpoint. There are 4 official rules for that, Are there? You have mentioned how IEEE 754 mandates rounding be performed when it is necessary in operations using IEEE 754 double precision floating point numbers, but that does not make those into "4 official rules" for converting a number into a string with exactly 2 decimal places. we can come with 5th, 6th etc. - as long as it provides predictable results. Given your public record on implementing rounding algorithms "we can come up with" seems a little optimistic. The limitations of IEEE-754 floating point are known to me better then Richard could imagine. Don't put money on it. You still do not appear to have comprehended that if 1.035 cannot ever be an IEEE 754 floating point number then it can also never be the number in "How do I convert a Number into a String with exactly 2 decimal places". Your continued obsession with that number is telling in this regard. Unfortunately fixed point systems on current 32- bit machines impose too narrow range of numbers to be universally usable. Bullshit. And you have been told why often enough by now. IEEE-754 floating point still remains as the most usable compromise for PCs (personal computers). Nonsense. But internal unbiased rounding algorithm of IEEE-754 based systems is irrelevant to this FAQ. Yes, we cannot represent exactly 2^52+1, 1/3, PI etc. etc. But we have to say exactly what will be 1.035 or -1.035 converted into a string with exactly 2 decimal places after comma. If 1.035 cannot be an IEEE 754 double precision floating point number then we can say with certainty that such a number can never be converted into a string with exactly 2 decimal places. All four official rules are giving exact answer on it. Not is the number cannot exist to start with. Both IE and Geck toFixed give the exact answer as well: but they are using different rules so these answers will be different. So the task is to decide who is right: IE, Gecko, no one; based on this decision a program has to be provided to ensure unifirmed results by fixing IE, or Gecko or both. Nobody misses the point quite so relentlessly as you do. Richard. Jan 29 '07 #11
 On Jan 29, 5:10 pm, "Richard Cornford" wrote: Are you asking which results the - toFixed - method of Number objects would return? There is a specified algorithm for - toFixed -, so its correct output is output that would be produced by applying the algorithm to the input. var n1 = 2.070; var n2 = n1/2; alert(n2 === 1.035); // true // but by Cornford's lemma: // 1.035.toFixed(2) is impossible // so futile to impose any rules So what you saying is: "I cannot predict any consistent behavior for the program, moreover it is silly to expect any consistent behavior out of it; but whatever it will output - it will be correct to take without questioning." Splendid! :-) Science and religion working together to unveil secrets of universe and stuff... :-) I can certainly state that IE's - toFixed - method is not implemented in accordance with the specification. A fire angel visited you to deliver this message or did you actually test it with a series of numbers? In the first case I have nothing but take your statement, as it is, in the second case what are these numbers? What was what "series"? The series of numbers you tried to round using native toFixed method to conclude that this method is buggy. Please past below in form "number"/"correct result"/"actual result". In case if no testing was made or if any empiric results are irrelevant by the definition of the matter then simply type in "fire angel" below. Where ECMAScript requires rounding the specification precisely states what rounding will happen and how it will happen. Rounding for an application context is determined by the context. For any given situation there are appropriate rounding strategies, which may be provided by features of the language or may need to be implemented with the language. It simply makes no sense to be talking of "what rounding rule is the most ECMAScript correct". But it does make sense to define what rounding result is correct and what is wrong? "bugs in IE toFixed implementation" FAQ says. An interesting approach. :-) That's getting like beating down a baby, really... But for all nasties you wrote before I can allow myself this little pleasure. Before posting I looked for some IEEE rounding online source suitable for junior school students - thus hopefully not hard enough for Mr.Crockford: obviously IEEE-754 specs in their pure form are beyond the level.
 On Jan 29, 7:58 pm, "VK"
 In comp.lang.javascript message , Sun, 28 Jan 2007 23:01:31, Richard Cornford Bullshit. You are failing to grasp that a numeric literal in sourcecode will result in a value of numeric type (following ECMA 262specified rules) but that numeric value will not necessarily be thenumber that may be expected from reading the numeric literal's text. OTOH, if you follow the link in the FAQ you can see that a quantity supplied as "1.035" and converted by unary + to a Number of exact value 1.034999999999999920063942226988729089498519897460 9375 can be rounded (traditional or Bankers') or truncated without undue difficulty (except by the VK standard) *as* *if* *it* *had* *been* *stored* *exactly*, in two quite distinct ways. -- (c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME. Web . Jan 29 '07 #14
 On Jan 29, 4:58 pm, "VK" >>Are you asking which results the - toFixed - method of Number objectswould return? There is a specified algorithm for - toFixed -, so itscorrect output is output that would be produced by applying the algorithmto the input. var n1 = 2.070; var n2 = n1/2; alert(n2 === 1.035); // true What do you imagine that is attempting to demonstrate? // but by Cornford's lemma: // 1.035.toFixed(2) is impossible // so futile to impose any rules I did not say that was impossible. There is no problem writing that code, it is understanding what it means that you are having trouble with. I said that it was imposable for - toFixed - to act upon a Number object with the value 1.035, because no numeric value in javascript can have the value 1.035. So what you saying is: "I cannot predict any consistent behavior for the program, moreover it is silly to expect any consistent behavior out of it; but whatever it will output - it will be correct to take without questioning." No, I am saying that I can precisely predict the outcome of - 1.035.toFixed(2) - in any ECMAScript implementation that does not suffer from bugs in the related areas. However, in making that prediction I would have to take the numeric literal source code "1.035" and transform it into an IEEE 754 double precision floating point number following the rules in ECMA 262 3rd Ed. section 7.8.3. The result of that process will _not_ be 1.035, but it is still the value of the Number object upon which the - toFixed - method will be called, and so the real input value for the - toFixed - algorithm. The question of how the - toFixed - method handles the number 1.035 is a nonsense because it is never presented with any number that cannot be precisely represented as an IEEE 754 double precision floating point number. Splendid! :-) Science and religion working together to unveil secrets of universe and stuff... :-) ? Is it really too much trouble to read the specification for the language you insist in babbling on about? >I can certainly state that IE's - toFixed - method is not implementedin accordance with the specification. A fire angel visited you to deliver this message or did you actually test it with a series of numbers? In the first case I have nothing but take your statement, as it is, in the second case what are these numbers? Some of these numbers (and there are many) are:- (-0.94).toFixed(0) (-0.88).toFixed(0) (-0.77).toFixed(0) (-0.66).toFixed(0) (-0.55).toFixed(0) - which all result in the string: "-0" (0.94).toFixed(0) (0.88).toFixed(0) (0.77).toFixed(0) (0.66).toFixed(0) (0.55).toFixed(0) - which all result in the string: "0" (0.094).toFixed(1) (0.088).toFixed(1) (0.077).toFixed(1) (0.066).toFixed(1) (0.055).toFixed(1) - which all result in the string: "0.0" (0.0094).toFixed(2) (0.0088).toFixed(2) (0.0077).toFixed(2) (0.0066).toFixed(2) (0.0055).toFixed(2) - which all result in the string: "0.00" (0.000000000000000064).toFixed(16) - which results in the string: "0.0000000000000000" None of these are results in accordance with the algorithm specified in ECMA 262 3rd Ed. >What was what "series"? >The series of numbers you tried to round using native toFixed method to conclude that this method is buggy. One single erroneous result is sufficient to conclude that any function/method is buggy. Please past below in form "number"/"correct result"/"actual result". In case if no testing was made or if any empiric results are irrelevant by the definition of the matter then simply type in "fire angel" below. The correct output from - (0.000000000000000064).toFixed(16) - is "0.0000000000000001", while IE outputs "0.0000000000000000". >Where ECMAScript requires rounding the specification precisely stateswhat rounding will happen and how it will happen. Rounding for anapplication context is determined by the context. For any givensituation there are appropriate rounding strategies, which may beprovided by features of the language or may need to be implementedwith the language. It simply makes no sense to be talking of "whatrounding rule is the most ECMAScript correct". But it does make sense to define what rounding result is correct and what is wrong? Not really. Various forms of rounding would produce results that disagree, yet all have valid application in some context or another. "bugs in IE toFixed implementation" FAQ says. An interesting approach. :-) There are bugs in IE's - toFixed - implementation, hence the obviously dubious results it outputs for so many values. That's getting like beating down a baby, really... But for all nasties you wrote before I can allow myself this little pleasure. Before posting I looked for some IEEE rounding online source suitable for junior school students - thus hopefully not hard enough for Mr.Crockford: obviously IEEE-754 specs in their pure form are beyond the level.
 VK wrote: On Jan 29, 7:58 pm, VK wrote: not hard enough for Mr.Crockford Cruze / Kruse Cornford / Crockford clj is really a challenge for dislexic people like I am :-) I don't have that much trouble, but then I am not arrogant enough to believe that I could not make a mistake and so would go and check the spelling of someone's name. _Mr. Cornford_ I meant This mistake is just another symptom of your delusion that you know what you are doing. It will keep you arguing this subject on and on until someone eventually manages to make you see that you have been utterly wrong from the outset. Richard. Jan 29 '07 #16
 In comp.lang.javascript message <11*********************@l53g2000cwa.goo glegroups.com>, Mon, 29 Jan 2007 04:14:55, VK posted: >On Jan 29, 2:23 pm, Erwin Moller >So if you are talking about 1.035 and want to store that in a variable,wonder how much bytes JavaScript has to represent the number.A simple example:var val1 = 1.12345;var val2 = 1.123456;var val3 = (val1-val2);alert (val3);This might be a good startingpoint to get an idea of what Richard isreffering to: Erwin, the FAQ in question is "How do I convert a Number into a Stringwith exactly 2 decimal places?" It seems that you have failed to notice that, in the Subject lines of FAQ Section 4 entries, words do not generally start with capital letters. " or "" (SonOfRFC1036) Jan 29 '07 #17
 Dr J R Stockton said the following on 1/29/2007 2:22 PM: Why are my Rollovers so slow? What is the bug and a proposed correction? The bug is that it doesn't even come close to answering the question. I did change it to rollover vice Rollover locally. Will get the minor corrections uploaded later today.
 In comp.lang.javascript message <11*********************@q2g2000cwa.goog legroups.com>, Mon, 29 Jan 2007 10:34:01, Richard Cornford There are bugs in IE's - toFixed - implementation, hence the obviouslydubious results it outputs for so many values. Be aware that DA posted, in news:m.p.s.j 20031106, javascript code said to follow ECMA-262-s specification step by step. It's in my Rounding 1. IMHO, it's less than ideal, since null and undefined are converted to "0.00" and "NaN" - but that may be what ECMA wants. -- (c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 6 news:comp.lang.javascript FAQ .
 In comp.lang.javascript message <-K********************@telcove.net>, Tue, 30 Jan 2007 07:55:08, Randy Webb Dr J R Stockton said the following on 1/29/2007 2:22 PM: > Why are my Rollovers so slow?What is the bug and a proposed correction? The bug in the Subject is the capital R. As a correction, I suggest a lower-case r. >

### This discussion thread is closed

Replies have been disabled for this discussion.