返回最接近的数字的多个值

时间:2010-04-24 17:58:12

标签: c#

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

我想要一个数字数组设置为16的neareast倍数,所以2 = 0,5 = 0,11 = 16,17 = 16,30 = 32等

感谢

6 个答案:

答案 0 :(得分:27)

为此,您需要进行一些划分和舍入:

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 :(得分:6)

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(我有错误地省略了。)

答案 2 :(得分:6)

您不需要进行任何浮点除法,这是不必要的。使用余数运算符:

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

答案 3 :(得分:2)

将中间向+∞

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

答案 4 :(得分: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 */

答案 5 :(得分: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