I’ve distilled an equation down to this:
speed = ( ( rear_wheel_speed_a + front_wheel_speed_a ) << 10 ) +
( ( rear_wheel_speed_b + front_wheel_speed_b ) << 2 );
but for some reason I’m getting unexpected results so I must be doing something wrong. This started out like this:
speed = ((((rear_wheel_speed_a * 256 + rear_wheel_speed_b) / 16) +
((front_wheel_speed_a * 256 + front_wheel_speed_b) / 16)) / 2) * 128;
That is the completely unsimplified version that does work. Are they not mathematically equivalents?
all values are signed 16 bit integers. An example data set is:
rear_wheel_speed_a = 0x03;
rear_wheel_speed_b = 0x6F; //<-- I originally swapped
front_wheel_speed_a = 0x02; //<-- these two values. Sorry!
front_wheel_speed_b = 0xE2;
That boils down to an answer of 6468. But in the first equation, my application behaves as though it is at least 3% smaller or larger. I say it like that because this is an embedded application where I have no way of confirming the outcome of the calculations other than to test if it is within a certain range of “normal”. When I use the 2nd equation it falls within the parameters but with my “simplified” (bit shifted) equation it does not so I think I must be doing the shifts incorrectly (or I simplified wrong but I triple checked it).
Any insight is appreciated, thank you.
From the second formula, I assume you operating 2 16bit values separated into their 8bit part a and b:
and the formula you using, can be simplified into speed=
(front_speed+rear_speed)*4.From your values, 0x6fe2*4 just can fit 16bit, so this value can be evaluated in 16-bit arithmetic. But the values look like their parts are arranged wrong, and I have a feeling that real values are 0x036f and 0x02e2 (or 0x03ea and 0x026f) – those values are close to each other, as should be expected from speed of two wheels.
Also it seems your formula is better, because it doesn’t introduce loss of precision on divide operations. But keep in mind, that if you’re using a good compiler (not always true for embedded applications) it usually converts divide/multiply to shifts itself when possible