All the previous implementations do not use rounding and thus have a large error:
Here's how to do this in fixed point math:
I'm using X.1u prevision (1 LSB is used for fraction part).
//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 factor is a fixed point (integer) too 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 fraction bits
- distance * factor has N+1 fraction bits
- (1 << N) is a 'half' as 1 << (N+1) is 'one' in the above fixed point precision.
After understanding each part, the above line can be compacted:
new_x = ( ((1 + center) << N) + (distance * factor) ) >> (N + 1)
The used integer type should be large enough, off course. If the valid range is unknown, one should check the input to this function and something else. In most cases this isn't needed.
This is as good as it get in fixed point math. This is how HW circuits perform integer math operations.