PDA

View Full Version : Math Tests



jscheuer1
10-16-2007, 07:19 AM
<script type="text/javascript">
alert(184.64-165.52)
</script>


<script type="text/javascript">
alert((280.84*100-165.52*100)/100)
</script>


On my lap top, even though these sorts of calculations usually provide the correct answer, neither of the above do. Any ideas?

Interestingly, if I do the first one with the multiply and divide stuff from the second, it comes out right. And if I do the second one as just a straight subtraction without the multiply and divide stuff, it also comes out right.

Win XP Media Edition - Opera 9.01, IE 7, and FF 2.0.0.7 all make the exact same errors.

tech_support
10-16-2007, 07:34 AM
Strange. What error/answer does it give you?

jscheuer1
10-16-2007, 07:46 AM
Try 'em out and see what you get, but I'm getting:


19.119999999999976


115.31999999999996

tech_support
10-16-2007, 07:51 AM
Same here. I'd say just round them. :p
JS maths is slightly less accurate than the maths done by the calculator, I guess. Try having a look at this (http://www.jibbering.com/faq/#FAQ4_7).

jscheuer1
10-16-2007, 08:13 AM
That's what I'm doing, rounding them. I wasn't really having a problem, so much as I wanted to know if anybody else was getting the same thing. I thought they probably would and that it was weird.

I discovered this because I have a complex script and batch file that generates from a csv file a printable data sheet for a client in the form of an HTML page that I can then attach to an email. Usually I just take the values as given in the text strings, but this time I need to subtract the previous balance of 165.52 to get the actual totals for this category of transaction.

I'm using:


money(Math.round((window[i][16]-165.52)*100)/100)

where window[i][16] represents the running balance with the previous balance included. My money() function is:


function money (n){
var c=n.toString(10).split('.')[1];
return n.toString(10)+(c&&c.length==2? '' : c&&c.length==1? '0' : '.00');
}

Seems to work out.

Notes: I only need this in FF, once I get the page in it, I use the Developer Extension to grab the generated source which is then cross browser. As a result, I've no idea (and don't need to) how cross browser any of the above code might or might not be.

Twey
10-16-2007, 12:59 PM
This will be the same in most languages. Floats in programming languages are stored in a binary form (as with any digital data), and since they can be infinite (1/3 anyone?) they get truncated. However, they're truncated in their binary representation, not their decimal one, so usually the truncated version isn't a clean round in decimal. This is why you should never compare two floats:
102.23952 === 102.23952 // WRONG... because depending on how large a float representation the interpreter/compiler uses, one of them may not be what you expect it to be. Instead, you should round both or test a range (> 102 and < 103, for example). See IEEE-754 (http://en.wikipedia.org/wiki/IEEE_floating-point_standard).

jscheuer1
10-16-2007, 03:24 PM
I since found a much easier way of dealing with this (with US currency, at least):


(window[i][16]-165.52).toFixed(2)

Twey
10-16-2007, 06:02 PM
Be aware that this yields a string.

jscheuer1
10-16-2007, 09:02 PM
Be aware that this yields a string.

And requires a number. It's tailor made for what I'm doing. I start out with a string that is formatted as US currency without the dollar sign (xx.xx, no comas). It becomes a number by virtue of subtracting 165.52 from it, then toFixed(2) turns it back into a rounded value to 2 decimal places string. Then I just slap on the dollar sign and it is ready for the report.

Supported since Javascript 1.5 - your (referring to everyone here) results may vary.

Trinithis
10-16-2007, 09:39 PM
If it is important enought, you could make your own number object that can hold any real-world rational number in it and do base 10 calculations (or something). Of course, the object could conceivably be rather inefficient.

Twey
10-18-2007, 04:19 PM
I don't think "rather" really covers it :) Still, I suppose it's hardly being used for animated particle physics, so I doubt it would matter too much.

I particularly like Lisp's manner of (at least partially) dealing with this sort of thing: fractions are a data type. That is, (/ 1 3) (one divided by three), rather than yielding a fixed-length decimal, yields a fraction 1/3, which can be calculated to a decimal value as necessary, and to the precision necessary.