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

时间:2018-12-17 17:45:06

标签: c# math calculation

我有一个任意的数值(浮点数)和一个任意的步长(也是浮点数)。

我想在步骤中找到最接近数值的数字,而无需花费很长的时间(直到到达为止)

示例: 步骤是5 值为1038

该步骤将执行0-5-10-15-...-1035-1040-...

因此,最接近的值是1040。通过循环查找该值非常容易,只需查找我的数字之前的最后一个值,之后的第一个值,然后选择更接近的值即可。

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

有没有一种方法可以仅通过计算而没有循环?

编辑:无需从0开始。步长可以是负数或正数(但步长-40与步长40完全相同)。如果通过聪明的计算而不是循环来完成,则不需要起点。

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

欢迎任何人知道如何更清楚地解释它(包括更改标题)

2 个答案:

答案 0 :(得分:3)

您可以使用数学来计算。首先,获取valuestep的绝对值,然后通过从step中减去value % step来获得低数,从而确定value两侧的数,并将step添加到较低的数字以获得较高的数字。

然后只需确定哪个数字更接近value并返回(但首先将其乘以value的符号)即可:

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

答案 1 :(得分:1)

那又怎么样:

        int step = 3;
        int value = 10;

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