Самый эффективный / элегантный способ обрезать номер? - PullRequest
42 голосов
/ 17 февраля 2012

Учитывая реальное (n), максимальное значение этого действительного значения может быть (верхнее), а минимальное значение этого действительного значения может быть (нижнее), как мы можем наиболее эффективно обрезать n, чтобы оно оставалось между нижним и верхним?

Конечно, можно использовать кучу операторов if, но это скучно! А как насчет более компактных и элегантных / забавных решений?

Моя собственная быстрая попытка (C / C ++):

float clip( float n, float lower, float upper )
{
    n = ( n > lower ) * n + !( n > lower ) * lower;
    return ( n < upper ) * n + !( n < upper ) * upper;
}

Я уверен, что есть и другие, лучшие способы сделать это, вот почему я выкладываю это там! ..

Ответы [ 13 ]

1 голос
/ 28 мая 2014
n = n + ((n < lower) * (lower - n)) + ((n > upper) * (upper - n));
0 голосов
/ 20 сентября 2013

Следующий файл заголовка должен работать для C и C ++.Обратите внимание, что он определяет min и max, если макросы уже определены:

#pragma once

#ifdef min
#undef min
#endif

#ifdef max
#undef max
#endif

#ifdef __cplusplus
#include <algorithm>

template <typename T>
T clip(T in, T low, T high)
{
    return std::min(std::max(in, low), high);
}
#else /* !__cplusplus */
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) < (b)) ? (b) : (a))
#define clip(a, b, c) min(max((a), (b)), (c))
#endif /* __cplusplus */
0 голосов
/ 17 февраля 2012

Если производительность действительно имеет значение для вас, как насчет встроенного решения, которое позволяет избежать назначения, когда не требуется:

#define clip(n, lower, upper) if (n < lower) n= lower; else if (n > upper) n= upper
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...