我有一个任意的数值(浮点数)和一个任意的步长(也是浮点数)。
我想在步骤中找到最接近数值的数字,而无需花费很长的时间(直到到达为止)
示例: 步骤是5 值为1038
该步骤将执行0-5-10-15-...-1035-1040-...
因此,最接近的值是1040。通过循环查找该值非常容易,只需查找我的数字之前的最后一个值,之后的第一个值,然后选择更接近的值即可。
但这是O(n),我想要更快的东西(有时步长很小,值很大,对于UI反应,这必须非常快地完成)。
有没有一种方法可以仅通过计算而没有循环?
编辑:无需从0开始。步长可以是负数或正数(但步长-40与步长40完全相同)。如果通过聪明的计算而不是循环来完成,则不需要起点。
英语不是我的母语。我很清楚“ step”可能是错误的词,但是我找不到合适的解释。我希望我的例子可以使我的问题更清楚。
欢迎任何人知道如何更清楚地解释它(包括更改标题)
答案 0 :(得分:3)
您可以使用数学来计算。首先,获取value
和step
的绝对值,然后通过从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...");
}
输出
答案 1 :(得分:1)
那又怎么样:
int step = 3;
int value = 10;
if ((value % step) == 0)
{
return value;
}
else
{
return ((value / step) + 1) * step;
}