代码之家  ›  专栏  ›  技术社区  ›  Kaito Kid

如何获取最接近我的数字的特定步骤的值

  •  -3
  • Kaito Kid  · 技术社区  · 6 年前

    我有一个任意的数值(float)和一个任意的步骤(也是float)。

    我想在步骤中找到最接近数值的数字,而不需要走很长的路(直到我到达为止)。

    例子: 步骤5 值是1038

    步骤是0-5-10-15--1035-1040-…

    因此,最接近的值是1040。这是很容易找到的循环,只需搜索我的数字之前的最后一个值,之后的第一个值,并选择一个更接近的值。

    但这是O(N),我想要更快的东西(有时步骤非常小,值非常大,这对于UI反应必须非常快地完成)。

    有没有一种方法可以做到这一点,只需要计算,而不需要循环?

    编辑:不需要从0开始。步骤可以是负的或正的(但是-40的步骤会得到与40的步骤完全相同的结果)。如果通过巧妙的计算而不是循环来完成,则不需要起点。

    英语不是我的母语。我很清楚“步骤”可能是个错误的词,但我找不到合适的词来解释。我希望我的例子能让我的问题更清楚。

    如果有人知道如何更清楚地解释(包括更改标题),欢迎编辑。

    2 回复  |  直到 6 年前
        1
  •  3
  •   Rufus L    6 年前

    你可以用数学计算出来。首先,得到 value step ,然后确定 减去 value % step 价值 对于低数字,并添加 对于较高的值,则为低值。

    然后确定哪个数字更接近 价值 然后返回(但首先乘以 价值 ):

    static float GetClosestNumber(float value, float step)
    {
        // Get the absolute values of our arguments
        var absValue = Math.Abs(value);
        step = Math.Abs(step);
    
        // Determing the numbers on either side of value
        var low = absValue - absValue % step;
        var high = low + step;
    
        // Return the closest one, multiplied by -1 if value < 0
        var result = absValue - low < high - absValue ? low : high;
        return result * Math.Sign(value);
    }
    

    下面是一些测试方法和相关类:

    class Item
    {
        public float Value { get; set; }
        public float Step { get; set; }
    }
    
    static void Main()
    {
        var testItems = new List<Item>
        {
            new Item {Value = 1038, Step = 5},
            new Item {Value = .8f, Step = .25f},
            new Item {Value = .9f, Step = .25f},
            new Item {Value = -86, Step = -45},
            new Item {Value = -168, Step = -45},
            new Item {Value = -168, Step = 45},
        };
    
        foreach (var testItem in testItems)
        {
            Console.WriteLine("The closest number to {0}\twhen stepping by {1}\tis {2}", 
                testItem.Value, testItem.Step, GetClosestNumber(testItem.Value, testItem.Step));
        }
    
        GetKeyFromUser("\nDone! Press any key to exit...");
    }
    

    输出

    enter image description here

        2
  •  1
  •   user3210023    6 年前

    如何:

            int step = 3;
            int value = 10;
    
            if ((value % step) == 0)
            {
                return value;
            }
            else
            {
                return ((value / step) + 1) * step;
            }