B.K.
B.K.

Reputation: 10172

Mapping one range of integers to another

Say that I have a set of numbers from 0 to 255 and I would like to be able to map that range to a smaller one of 0 through 63, so that each value in the smaller set represents four values from the larger set. I haven't been able to find anything in standard C# that would allow me to do that.

I can do so manually if I know all of the values ahead of time, by dividing an input by 4, i.e.:

int input = 127;
int pInput = 127 / 4; // 31

The major problem with that method is that it's not entirely usable to me, due to the fact that my number sets will vary in their ranges. I could take the larger set and divide it by the smaller set to get the divisor value, which would be placed where the 4 is:

int divisor = lSet.Count / sSet.Count;  // 256 / 64 = 4
int pInput = input / divisor;           // 127 / 4 = 31

...but it's not an entirely accurate method, considering I'm dealing with integer values and the divisor won't always be accurate.

Has anyone dealt with something like this or has a possible solution?

EDIT:

To clarify the goal here, say that you have a range of inputs of 0 through 255, but you can only process numbers of 0 through 63. I want to map the two ranges, so that if any input from the larger set maps to a particular value in the lower set. Note that there can be different sets, and the ones I use are simply as examples.

It's possible to have a set of 0 through 136 and a set of 0 through 25. The above formula won't properly map the two, since the divisor would be 5 and the top value of 136 would not map to the value of 25. It would instead map to 27, which is out of range. m-y's solution would not work here either.

Here's an illustration that doesn't rely on numbers, but rather a concept:

|     n1    |     n2    |     n3    | ... |     ni    |
| n1 ... nm | nm ... nq | nq ... nr | ... | nj ... ni |

Upvotes: 0

Views: 3726

Answers (1)

myermian
myermian

Reputation: 32525

You could use the modulus operator, %:

var result = x % 64;

Update: I'll expand on my answer. The modulus operator will give the remainder after division. So, in this situation 0 % 64 = 0, 1 % 64 = 1, ... 63 % 64 = 63, 64 % 64 = 0, 65 % 64 = 1, etc ...


In the example above, the modulus operator would map the values of (0, 64, 128, 192) to 0, (1, 65, 129, 193) to 1, ... (63, 127, 191, 255) to 63. But, if you are looking to create the sets in the format of (0, 1, 2, 3) = 1, (4, 5, 6, 7) = 2, ..., (252, 253, 254, 255) = 63. Then you have the right answer already:

var divisor = (double)largeSet.Count / smallSet.Count;
var result = x / divisor;

If you are worried about zero-based numbers, i.e. the x you pass in is 256 (which is 255 in zero based), then simply subtract one first:

 var result = (x - 1) / divisor;
 // (256 - 1) / 4
 // 255 / 4 = 63.

Upvotes: 5

Related Questions