Quote:
Originally Posted by mosier
Code:
unsigned long Trip::mph(){
// if(seconds<2) //i.e. instant
// return vssPulsesPerMile*10000/(currentVSS*36);
if(vssPulses<1000)
return (vssPulses*3600000)/(vssPulsesPerMile*seconds);
return (vssPulses*3600)/(vssPulsesPerMile*seconds/1000);
}
both returns return the same value, unless I'm completely going about it the wrong way. The 1000 in the second return is the same as just multiplying the (vssPulses*3600) by 1000..

It's a little tricky, it is a 32 bit integer number and scaling thing. The largest number we can can represent is 2^32, or a little over 4 billion. The general rule of thumb with integer math (as far as I know) is to do your multiplications in the numerator first and then the divisions. i.e. If I wanted 2*3/2, and I did the (3/2) first, the answer would be 2, but if I do the (2*3) first, I get the correct answer, 3.
As long as vssPulses is less than 1000, we are safe to multiply it by 3600000 without overflow, as it will be less than 4 billion, and we don't lose any resolution in the deniminator.
if vssPulses is greater than 1000, we have to scale down the equation so the numerator doesn't overflow. We can also better afford to scale down the denominator since we *should* have a larger number there, but it isn't perfect. There are some intermediate values there that could close the gap, or a modification that predicts how much to multiply the numerator and/or divide the denominator by to preserve accuracy and prevent overflow.
We are here because the 64 bit libraries are huge. I suppose we could just go look and see how they do it too