View Full Version : Most bizzare calculation ???
ngaisteve1
01-29-2003, 12:14 AM
I got a very bizzare bugs here.
Eg of input
Country: Malaysia - West (Others)
Type: Document
Weight: 0.5
Total Price: 10
{same}
Weight: 0.6
Total Price: 11.2
{same}
Weight: 0.7
Total Price: 12.4
{same}
Weight: 0.8
Total Price: 14.8 (???)
How come when weight 0.8, it jump to 14.8 instead of 13.6? Anyone knows how to fix it? Thanks.
Link also available in http://www.citylinkexpress.com/singapore/rate_calculation.asp
kdjoergensen
01-29-2003, 09:41 AM
It is because of a mathematical rounding issue in javascript. The 0.8 weight is actually the correct one.
Try to run below alert just below the line in which tmpTotalPrice is calculated:
alert((tmpWeight - 0.5) * 10);
If you input 0.6 as weight you would expect:
you would expect: 0.6 - 0.5 = 0.1 * 10 = 1
However, this is the result: 0.9999999999999998
as you can see, when using parseInt around the above expression you will in effect reduce it to 0. I know you are compensating for that by adding 1, but that is REALLY not a very good way of getting around the rounding problem
Now input 0.7 as the weight
you would expect: 0.7 - 0.5 = 0.2 * 10 = 2
however, the result is: 1.9999999999999995
again it is rounding down to 1 (instead of up to 2)
Ok, now input 0.8 as weight
you would expect: 0.8 - 0.5 = 0.3 * 10 = 3
however, the result is: 3.00000000000000004
If you then try to compensate for the problems experienced above and add 1 then you jump from an expected 13.8 to 14.8
The problem with your script is that the internal math generator in javascript is not very precise (rounding problem).
Solution: instead of using phaseInt to round off, you need to use a Math.Round() method.
This will round 0.9999999999999998 to 1.0 and 3.00000000000000004 to 3 and then there is no reason to add 1 to compensate.
ngaisteve1
01-29-2003, 08:20 PM
Thanks for the reply but just want let you know that actually the reason the formula is like is because of the rating system.
from 0 g to 500 g = $13
add 100 g (501 g - 600 g) = $1.60
eg
0.2 kg = $13
0.5 kg = $13
0.55 kg = $14.60
0.6 kg = $14.60
0.7 kg = $16.20
If use math.round
The formula is
if more than 0.5 kg, then
price is 13 + ((parseInt((tmpWeight - 0.5) * 10) + 1) * 1.6)
kdjoergensen
01-30-2003, 05:26 PM
My point here again:
parseInt always round down. parseInt do not do a good job of rounding, because what logically should add up to '1' (whole number) gets "rounded" to 0.9999999998 which will result in zero (0) when using parseInt. If you instead use math.round then calculations which intuiatively should add up to 1 will also be rounded up to 1.
example:
400-600 = 200 / 200 = 1
price = 13 + ((math.Round((tmpWeight - 0.5) * 10)) * 1.6);
example:
tmpWeight = 0.8
math.Round((0.8-0.5 = 0.3)*10) = 3 * 1.6 = 4.6
price = 13 + ((parseInt((tmpWeight - 0.5) * 10)+1) * 1.6);
tmpWeight = 0.8
parseInt((0.8-0.5 = 0.3)*10) = 2 +1 = 3 * 1.6 = 4.6
So if you want math.Round to work then take out the extra addition of '1'. This extra addition of one you added to make up for the 'ineffeciencies' of parseInt and which is what causes your problems when the weight "Jumps" to 14.6 because parseInt suddenly do not need the extra one added.
So remove the addition of one, and use math.Round instead of parseInt.
ngaisteve1
01-30-2003, 10:23 PM
I still got the same result, kdjoergensen. Is Math.round really works btw? This is my amended file.
vBulletin® v3.6.7, Copyright ©2000-2009, Jelsoft Enterprises Ltd.