Как получить значение на конкретном шаге, ближайшем к моему номеру - PullRequest
0 голосов
/ 17 декабря 2018

У меня есть произвольное числовое значение (с плавающей запятой) и произвольный шаг (также с плавающей запятой).

Я хочу найти число на шаге, которое будет ближайшим к числовому значению, не переходядлинный путь (шагая, пока я не достигну его)

Пример: шаг 5 Значение 1038

шаг будет идти 0 - 5 - 10 - 15 - ... - 1035 -1040 - ...

Поэтому самое близкое значение - 1040. Это очень легко найти с помощью цикла, который просто ищет последнее значение перед моим числом, первое значение после и выбирает более близкое.

Но это O (n), и я хочу что-то быстрее (иногда шаг очень маленький и значение очень большое, и это должно быть сделано очень быстро для реакций пользовательского интерфейса).

IsЕсть ли способ сделать это с помощью только вычисления, без цикла?

РЕДАКТИРОВАТЬ: нет необходимости начинать с 0. Шаг может быть отрицательным или положительным (но шаг -40 даст точныйтакой же результат, как шаг 40).Если это делается с помощью умного вычисления вместо цикла, начальная точка не требуется.

Английский не является моим родным языком.Я хорошо знаю, что слово «шаг», вероятно, неправильное слово, но я не могу найти правильное объяснение.Надеюсь, мой пример прояснит мой вопрос.

Редактирование приветствуется, если кто-нибудь знает, как объяснить его более четко (включая изменение названия)

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

А как же:

        int step = 3;
        int value = 10;

        if ((value % step) == 0)
        {
            return value;
        }
        else
        {
            return ((value / step) + 1) * step;
        }
0 голосов
/ 17 декабря 2018

Вы можете просто использовать математику, чтобы понять это.Сначала получите абсолютные значения 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...");
}

Выход

enter image description here

...