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.
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)
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.
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.
Powered by vBulletin® Version 4.2.2 Copyright © 2019 vBulletin Solutions, Inc. All rights reserved.