var quantity = $(this).find('td:eq(2) input').val()*1;
var unitprice = $(this).find('td:eq(3) input').val()*1;
var totaltax = 0;
$(this).find('td:eq(4) input[name^=taxamount]').each(function(){
totaltax = (totaltax*1)+($(this).val()*1);
});
var subtotal = (unitprice+totaltax);
alert(subtotal+' is unit subtotal, to mulitply by '+quantity);
var total = subtotal*quantity;
$(this).find('td:last').html('$'+total);
In this case, based on my DOM, the results are all integers (especially because I'm making sure I apply the *1 modifier to values to ensure they are numbers, not strings).
In this case, these are teh values returned within the first 7 lines of the above code (and verified through alert mand) quantity: 10 unitprice: 29 totaltax: 3.48 subtotal = 32.48
When I multiply subtotal*quantity for the total variable, total returns: total: 324.79999999999995
So at the end, I get the td:last filled with $324.79999999999995 rather than $324.80 which would be more correct.
Bizarre, I know. I tried all sorts of alerts at different points to ensure there were no errors etc.
var quantity = $(this).find('td:eq(2) input').val()*1;
var unitprice = $(this).find('td:eq(3) input').val()*1;
var totaltax = 0;
$(this).find('td:eq(4) input[name^=taxamount]').each(function(){
totaltax = (totaltax*1)+($(this).val()*1);
});
var subtotal = (unitprice+totaltax);
alert(subtotal+' is unit subtotal, to mulitply by '+quantity);
var total = subtotal*quantity;
$(this).find('td:last').html('$'+total);
In this case, based on my DOM, the results are all integers (especially because I'm making sure I apply the *1 modifier to values to ensure they are numbers, not strings).
In this case, these are teh values returned within the first 7 lines of the above code (and verified through alert mand) quantity: 10 unitprice: 29 totaltax: 3.48 subtotal = 32.48
When I multiply subtotal*quantity for the total variable, total returns: total: 324.79999999999995
So at the end, I get the td:last filled with $324.79999999999995 rather than $324.80 which would be more correct.
Bizarre, I know. I tried all sorts of alerts at different points to ensure there were no errors etc.
Share Improve this question edited Aug 9, 2011 at 22:21 Jacek Kaniuk 5,22927 silver badges28 bronze badges asked Aug 9, 2011 at 22:15 jeffkeejeffkee 5,23812 gold badges47 silver badges79 bronze badges 7- 5 no, it isn't bizarre. simple floating-point arithemtic. – Karoly Horvath Commented Aug 9, 2011 at 22:17
- 1 Wele to the world of floating point arithmetic. – zzzzBov Commented Aug 9, 2011 at 22:17
- floating point arithmetic: download.oracle./docs/cd/E19957-01/806-3568/… – BrokenGlass Commented Aug 9, 2011 at 22:17
- 1 See here – bfavaretto Commented Aug 9, 2011 at 22:17
-
Should not rely on floating point numbers for money calculations. @Sparky - I think the title is wrong - it should be
32.48 * 10
. – Anurag Commented Aug 9, 2011 at 22:22
7 Answers
Reset to default 7This has been asked one bizillion times.
Please read: What Every Computer Scientist Should Know About Floating-Point Arithmetic
You're ing up against a familiar issue with floating point values: certain values can't be precisely represented in a finite binary floating point number.
See here:
How to deal with floating point number precision in JavaScript?
This is the way floating point numbers work. There's nothing bizarre going on here.
I'd remend that you round the value appropriately for display.
That's the joy of floating point arithmetic -- some base 10 decimals cannot be represented in binary.
http://en.wikipedia/wiki/Floating_point#Accuracy_problems
Computers can't handle decimals very well in binary since in real mathematics there are literally an infinite number of values between 0.01 and 0.02 for example. So they need to store approximations, and when you do arithmetic on those approximations the results can get a little away from the true result.
You can fix it with (Math.round(total*100)/100).toFixed(2);
As others have mentioned, this is the way its meant to work. A suggested workaround can be found below:
var v = "324.32999999999995";
function roundFloat(n, d) {
var a= Math.pow(10, d);
var b= Math.round(n * a) / a;
return b;
}
$("body").append(roundFloat(v,3));
Where v
would be replaced with the desired value.
You can view the working example at: http://jsfiddle/QZXhc/
You could try rounding to 2 decimal digits as workaround
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744929587a4601650.html
评论列表(0条)