2010-04-24 66 views
4

我需要一个函数,我可以将一个数字转换为给定倍数的最接近的值。返回一个数字的最接近的多个值

例如我想要数目的阵列被设置为16的neareast倍数,所以2 = 0,5 = 0,11 = 16,17 = 16,30 = 32等

感谢

回答

23

一些划分和舍入应该是您需要的全部内容:

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?! 
+1

这个工程......朴实:) – mouthpiec 2010-04-24 18:14:08

6

16*((n+8)/16)是你想要的公式,如果,特别是要转换为8〜16(它同样接近0到16,所以这是不可能的,以决定如何将它完全基于转换“最接近的倍数”的概念,你必须决定! - ),当然一贯24到32,40到48,等等。如果您宁愿将8转换为0而不是16(以及始终为24至16等等),请使用+7来代替+8

为了代替硬编码16的使用通用X,则公式是X*((n+X/2)/X)(具有相同的条件如在上面段落如果X是偶数)。

编辑:没有必要惹浮点数其他答案建议,但你需要通过X乘回来(我曾错误地省略)左右。

+1

(N + 8)/ 16不起作用。尝试,说11.(11 + 8)/ 16 = 19/16。我认为你是依靠在这里划分截断,所以19/16 = 1.但11应该舍入到16,所以你仍然需要乘以16才能得到正确的答案。 – Ponkadoodle 2010-04-24 18:09:14

+0

@wallacolo,你是对的 - 我忘了加倍回去 - 编辑修复。 – 2010-04-24 18:13:12

4

你不需要做任何浮点除法,这是不必要的。使用求余运算符:

int rem = value % multiple; 
int result = value - rem; 
if (rem > (multiple/2)) 
    result += multiple; 
2

舍中间朝着+∞

int RoundNearest16(int value) 
{ 
    return (value + 8) & ~0xF; 
} 
+0

其他数字呢?例如5 – 2015-11-14 08:12:46

0

的情况下是一个比较复杂一点,如果多小于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 */ 
0

如果四舍五入到最接近的浮点数的倍数,您可以使用:

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