View Single Post
Old 05-19-2008, 12:49 AM   #86 (permalink)
needs more cowbell
dcb's Avatar
Join Date: Feb 2008
Posts: 5,038

pimp mobile - '81 suzuki gs 250 t
90 day: 96.29 mpg (US)

schnitzel - '01 Volkswagen Golf TDI
90 day: 53.56 mpg (US)
Thanks: 158
Thanked 269 Times in 212 Posts
Originally Posted by mosier View Post
unsigned long Trip::mph(){
//  if(seconds<2) //i.e. instant
//    return vssPulsesPerMile*10000/(currentVSS*36);
    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
  Reply With Quote