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

C# 如何获取最接近我的数字的特定步骤上的值,c#,math,calculation,C#,Math,Calculation,我有一个任意的数值(float)和一个任意的步长(也是float) 我想在步长上找到最接近数值的数字,而不需要走太远的路(直到我到达为止) 例如: 步骤是5 值是1038 这一步是0-5-10-15-1035-1040- 因此,最接近的值为1040。这很容易找到,只需循环搜索我的数字之前的最后一个值,后面的第一个值,然后选择更接近的值 但这是O(n),我想要更快的东西(有时步骤非常小,值非常大,对于UI反应,这必须非常快地完成) 有没有一种方法可以只进行一次计算而不进行循环 编辑:不需要从0开始

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

我想在步长上找到最接近数值的数字,而不需要走太远的路(直到我到达为止)

例如: 步骤是5 值是1038

这一步是0-5-10-15-1035-1040-

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

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

有没有一种方法可以只进行一次计算而不进行循环

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

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


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

你可以用数学来解释。首先,获得
value
step
的绝对值,然后通过从
value
中减去
value%step
来确定
step
两侧的数字,对于较低的数字,将
step
添加到较低的数字中

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

静态浮点GetClosestNumber(浮点值,浮点步长)
{
//获取参数的绝对值
var absValue=Math.Abs(值);
步骤=数学Abs(步骤);
//确定值两边的数字
var low=absValue-absValue%步长;
var高=低+阶跃;
//返回最接近的一个,如果值小于0,则乘以-1
var结果=absValue-低<高-absValue?低:高;
返回结果*数学符号(值);
}
下面是一个小测试方法和相关类:

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...");
}
类项目
{
公共浮点值{get;set;}
公共浮点步骤{get;set;}
}
静态void Main()
{
var testItems=新列表
{
新项{Value=1038,Step=5},
新项{Value=.8f,Step=.25f},
新项{Value=.9f,Step=.25f},
新项{Value=-86,Step=-45},
新项{Value=-168,Step=-45},
新项{Value=-168,Step=45},
};
foreach(测试项中的var测试项)
{
WriteLine(“当通过{1}\tis{2}步进时,与{0}\t最近的数字”,
testItem.Value,testItem.Step,GetClosestNumber(testItem.Value,testItem.Step));
}
GetKeyFromUser(“\n完成!按任意键退出…”);
}
输出

关于:

        int step = 3;
        int value = 10;

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

你试过什么?共享代码除非你创建一个散列,否则你不会得到比平均N/2更好的结果。如果只执行一次,则创建哈希的时间大于N/2。如果你做了很多次,Hash只会带来改进。你没有注意到他说的值和步长值都是浮点数。我承认问题中没有明确说明这一点,但你的答案不能很好地处理负数(浮点数可以是负数)。例如,-86的步数为45将得到-45,而-90将非常接近我的测试用例中的一个,数字为-168,而步骤:45的步数为-90(实际上应该是-180)@KaitoKid哦,我看到你使用了一个正的
步数
和一个负的
。我添加了一个条件,如果
value
step
没有相同的符号,则始终返回零(因为step总是从零开始,所以
value
step
必须位于
0
的同一侧)。好的,我明白你的意思了。我修改了该方法以考虑到这一点,方法是使用
value
step
的绝对值来确定
value
两侧的数字,然后返回与
value
符号相乘的结束值……不要忘记0
        int step = 3;
        int value = 10;

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