All previous implementations do not use rounding and, therefore, have a big mistake: Here, how to do this in fixed-point math: I use X.1u prevision (1 LSB is used for a fraction).
//center = (max_x + min_x) / 2 center = max_x + min_x // zero error here // distance = old_x - center distance = (old_x << 1) - center // zero error here //new_x = center + (distance * factor) new_x = (**1** + center + (distance * factor)) >> 1 return new_x
If the factor is a fixed point (integer) also with N bits describing the fraction, then new_x can be calculated as:
new_x = ( (1 << N) + (center << N) + (distance * factor) ) >> (N + 1)
- (center <N) has N + 1 bit fractions
- Distance * Factor has bit bit N + 1
- (1 <N) represents "half" as 1 <(N + 1) is "one" in the above fixed-point precision.
After understanding each part, the above line can be summarized:
new_x = ( ((1 + center) << N) + (distance * factor) ) >> (N + 1)
The integer type used should be large enough, of course. If the valid range is unknown, you should check the input of this function and something else. In most cases this is not required.
This is just as good as fixed-point math. This is how HW circuits perform entire mathematical operations.
egur
source share