Mapping a numeric range onto another Ask Question

Mapping a numeric range onto another Ask Question

Math was never my strong suit in school :(

int input_start = 0;    // The lowest number of the range input.
int input_end = 254;    // The largest number of the range input.
int output_start = 500; // The lowest number of the range output.
int output_end = 5500;  // The largest number of the range output.

int input = 127; // Input value.
int output = 0;

How can I convert the input value to the corresponding output value of that range?

For example, an input value of "0" would equal an output value of "500", an input value of "254" would equal an output value of "5500". I can't figure out how to calculate an output value if an input value is say 50 or 101.

I'm sure it's simple, I can't think right now :)

Edit: I just need whole numbers, no fractions or anything.

ベストアンサー1

Let's forget the math and try to solve this intuitively.

First, if we want to map input numbers in the range [0, x] to output range [0, y], we just need to scale by an appropriate amount. 0 goes to 0, x goes to y, and a number t will go to (y/x)*t.

So, let's reduce your problem to the above simpler problem.

An input range of [input_start, input_end] has input_end - input_start + 1 numbers. So it's equivalent to a range of [0, r], where r = input_end - input_start.

Similarly, the output range is equivalent to [0, R], where R = output_end - output_start.

An input of input is equivalent to x = input - input_start. This, from the first paragraph will translate to y = (R/r)*x. Then, we can translate the y value back to the original output range by adding output_start: output = output_start + y.

This gives us:

output = output_start + ((output_end - output_start) / (input_end - input_start)) * (input - input_start)

Or, another way:

/* Note, "slope" below is a constant for given numbers, so if you are calculating
   a lot of output values, it makes sense to calculate it once.  It also makes
   understanding the code easier */
slope = (output_end - output_start) / (input_end - input_start)
output = output_start + slope * (input - input_start)

さて、これは C であり、C での除算は切り捨てられるので、浮動小数点で計算してより正確な答えを得るようにしてください。

double slope = 1.0 * (output_end - output_start) / (input_end - input_start)
output = output_start + slope * (input - input_start)

さらに正確にしたい場合は、最後のステップで切り捨てではなく丸めを行います。これは、簡単なround関数を記述することで実現できます。

#include <math.h>
double round(double d)
{
    return floor(d + 0.5);
}

それから:

output = output_start + round(slope * (input - input_start))

おすすめ記事