返回最接近的数字的多个值
我需要一个函数,通过该函数我可以将数字转换为给定倍数的最接近值。
例如,我想要一个数字数组设置为16的neareast倍数,所以2 = 0,5 = 0,11 = 16,17 = 16,30 = 32等
谢谢
一些除法和舍入应该是你需要的所有:
int value = 30; int factor = 16; int nearestMultiple = (int)Math.Round( (value / (double)factor), MidpointRounding.AwayFromZero ) * factor;
小心使用这种技术。 Math.Round(double)
重载认为邪恶的突变体MidpointRounding.ToEven
是最好的默认行为,即使我们在学校之前学到的是CLR称之为MidpointRounding.AwayFromZero
。 例如:
var x = Math.Round(1.5); // x is 2.0, like you'd expect x = Math.Round(0.5); // x is 0. WAT?!
16*((n+8)/16)
是你想要的公式,特别是你要将8转换为16(它同样接近0到16,所以不可能决定如何基于它转换它“最接近的多重”概念,你必须决定! – ),当然一直是24到32,40到48,等等。 如果您宁愿将8转换为0而不是16(并且始终为24到16,依此类推),请使用+7
代替+8
。
为了使用通用X
代替硬编码的16
,则公式为X*((n+X/2)/X)
(如果X
是偶数,则具有与上段中相同的条件)。
编辑 :不需要像其他答案所暗示的那样乱用浮点数,但你需要乘以X
(我错误地省略了)。
你不需要做任何浮点除法,这是不必要的。 使用余数运算符:
int rem = value % multiple; int result = value - rem; if (rem > (multiple / 2)) result += multiple;
将中间朝向+∞
int RoundNearest16(int value) { return (value + 8) & ~0xF; }
如果倍数小于1,则情况稍微复杂一点。我写了这个通用函数:
public float NearestRound(float x, float delX) { if (delX < 1) { float i = (float)Math.Floor(x); float x2 = i; while ((x2 += delX) < x) ; float x1 = x2 - delX; return (Math.Abs(x - x1) < Math.Abs(x - x2)) ? x1 : x2; } else { return (float)Math.Round(x / delX, MidpointRounding.AwayFromZero) * delX; } } /* Sample: x: 101 multiple:2 NearestRound -> 102 x: 107 multiple:2 NearestRound -> 108 x: 100.9 multiple:2 NearestRound -> 100 x: 1 multiple:0.25 NearestRound -> 1 x: 1.35 multiple:0.25 NearestRound -> 1.25 x: 1.77 multiple:0.25 NearestRound -> 1.75 x: 1.9 multiple:0.25 NearestRound -> 2 */
如果舍入到最接近浮点数的倍数,您可以使用:
public static float convert(float value, float multipleOf) { return (float) Math.Round((decimal)value / (decimal)multipleOf, MidpointRounding.AwayFromZero) * multipleOf; }
然后你可以使用这样的函数:
Console.WriteLine("Convert 10.723: " + convert(10.723f, 0.5f)); // 10.5