假设我有一组从0
到255
的数字,我希望能够将该范围映射到0
到63
中的较小范围,以便较小集合中的每个值代表较大集合中的四个值。我无法在标准C#中找到任何可以让我这样做的东西。
如果我提前知道所有值,可以通过将输入除以4来手动完成,即:
int input = 127;
int pInput = 127 / 4; // 31
该方法的主要问题是它并不完全可用,因为我的数字集的范围会有所不同。我可以使用较大的集合并将其除以较小的集合以获得除数值,该除数值将放在4
所在的位置:
int divisor = lSet.Count / sSet.Count; // 256 / 64 = 4
int pInput = input / divisor; // 127 / 4 = 31
...但这并不是一个完全准确的方法,因为我正在处理整数值而且除数并不总是准确的。
有没有人处理过这样的事情或有可能的解决方案?
修改
要澄清此处的目标,请说明您有0
到255
的一系列输入,但您只能处理0
到63
的数量。我想映射两个范围,以便如果较大集合中的任何输入映射到较低集合中的特定值。请注意,可以有不同的集合,我使用的集合仅作为示例。
可以设置一组0
到136
以及一组0
到25
。由于除数为5
且136
的最高值不会映射到25
的值,因此上述公式无法正确映射这两者。它会映射到27
,这超出了范围。 m-y的解决方案也不适用于此。
这是一个不依赖于数字的插图,而是一个概念:
| n1 | n2 | n3 | ... | ni |
| n1 ... nm | nm ... nq | nq ... nr | ... | nj ... ni |
答案 0 :(得分:4)
您可以使用模数运算符%
:
var result = x % 64;
更新:我会扩展我的答案。模数运算符将在除法后给出余数。因此,在这种情况下0 % 64 = 0
,1 % 64 = 1
,... 63 % 64 = 63
,64 % 64 = 0
,65 % 64 = 1
等......
<小时/> 在上面的示例中,模数运算符会将(0,64,128,192)的值映射到0,(1,65,129,193)到1,...(63,127,191,255)到63.但是,如果你想以(0,1,2,3)= 1,(4,5,6,7)= 2,...,(252,253,254)的格式创建集合,255)= 63.那么你已经有了正确的答案:
var divisor = (double)largeSet.Count / smallSet.Count;
var result = x / divisor;
如果你担心从零开始的数字,即你传入的x是256(基于零的255),那么先简单地减去一个:
var result = (x - 1) / divisor;
// (256 - 1) / 4
// 255 / 4 = 63.