Returning the nearest multiple value of a number

前端 未结 6 1589
灰色年华
灰色年华 2020-11-29 08:33

I need a function by which I will be able to convert a number to a nearest value of a given multiple.

Eg i want an array of number to be set to the neareast multiple

相关标签:
6条回答
  • 2020-11-29 09:20

    Rounds the middle towards +∞

    int RoundNearest16(int value)
    {
        return (value + 8) & ~0xF;
    }
    
    0 讨论(0)
  • You don't need to do any floating point division, it's unnecessary. Use the remainder operator:

    int rem = value % multiple;
    int result = value - rem;
    if (rem > (multiple / 2))
        result += multiple;
    
    0 讨论(0)
  • 2020-11-29 09:32

    The case is a bit more complicated if the multiple is less than 1. I wrote this general function:

    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 讨论(0)
  • 2020-11-29 09:36

    16*((n+8)/16) is the formula you want if, in particular, you want to convert 8 to 16 (it's equally close to 0 as to 16, so it's impossible to decide how to convert it based exclusively on the "nearest multiple" concept, you have to decide!-), and of course consistently 24 to 32, 40 to 48, and so forth. Use +7 in lieu of +8 if you'd rather convert 8 to 0 rather than to 16 (and consistently 24 to 16, and so forth).

    To use a generic X in lieu of the hardcoded 16, then the formula is X*((n+X/2)/X) (with the same proviso as in the above paragraph if X is even).

    Edit: no need to mess around with floating point numbers as other answers suggest, but you do need to multiply back by X (which I had erroneously omitted).

    0 讨论(0)
  • 2020-11-29 09:37

    Some division and rounding should be all you need for this:

    int value = 30;
    int factor = 16;
    int nearestMultiple = 
            (int)Math.Round(
                 (value / (double)factor),
                 MidpointRounding.AwayFromZero
             ) * factor;
    

    Be careful using this technique. The Math.Round(double) overload believes the evil mutant MidpointRounding.ToEven is the best default behavior, even though what we all learned before in school is what the CLR calls MidpointRounding.AwayFromZero. For example:

    var x = Math.Round(1.5); // x is 2.0, like you'd expect
    x = Math.Round(0.5); // x is 0. WAT?!
    
    0 讨论(0)
  • 2020-11-29 09:38

    In case of rounding of to the nearest multiple of a float, you can use this:

    public static float convert(float value, float multipleOf) 
    {
        return (float) Math.Round((decimal)value / (decimal)multipleOf, MidpointRounding.AwayFromZero) * multipleOf;
    }
    

    Then you can use the function like this:

    Console.WriteLine("Convert 10.723: " + convert(10.723f, 0.5f)); // 10.5
    
    0 讨论(0)
提交回复
热议问题